提交 59906dd4 编写于 作者: M MaxKey

Temporal support , Column insertable & updatable

上级 76a0c3c9
......@@ -17,14 +17,15 @@
package org.dromara.mybatis.jpa.id;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IdentifierGeneratorFactory {
private static final Logger _logger = LoggerFactory.getLogger(IdentifierGeneratorFactory.class);
public static ConcurrentHashMap<String, IdentifierGenerator> generatorStrategyMap = new ConcurrentHashMap<String, IdentifierGenerator>();
public static ConcurrentHashMap<String, IdentifierGenerator>identifierGeneratorMap = new ConcurrentHashMap<String, IdentifierGenerator>();
public IdentifierGeneratorFactory() {
register(IdStrategy.UUID , new UUIDGenerator());
......@@ -42,26 +43,30 @@ public class IdentifierGeneratorFactory {
register(IdStrategy.SNOWFLAKEID, new SnowFlakeIdGenerator(datacenterId,machineId));
}
public ConcurrentHashMap<String, IdentifierGenerator> getGeneratorStrategyMap() {
return generatorStrategyMap;
public static ConcurrentHashMap<String, IdentifierGenerator> getIdentifierGeneratorMap() {
return identifierGeneratorMap;
}
public void setGeneratorStrategyMap(ConcurrentHashMap<String, IdentifierGenerator> generatorStrategyMap) {
for (Map.Entry<String, IdentifierGenerator> entry : generatorStrategyMap.entrySet()) {
register(entry.getKey(),entry.getValue());
}
public static void setIdentifierGeneratorMap(ConcurrentHashMap<String, IdentifierGenerator> identifierGeneratorMap) {
IdentifierGeneratorFactory.identifierGeneratorMap = identifierGeneratorMap;
}
public void register(String strategy, IdentifierGenerator generator) {
if(IdentifierGeneratorFactory.generatorStrategyMap.containsKey(strategy)) {
strategy = strategy.toLowerCase();
if(IdentifierGeneratorFactory.identifierGeneratorMap.containsKey(strategy)) {
return;
}
IdentifierGeneratorFactory.generatorStrategyMap.put(strategy, generator);
IdentifierGeneratorFactory.identifierGeneratorMap.put(strategy, generator);
_logger.debug( "Registering IdentifierGenerator strategy [{}] -> [{}]", strategy, generator.getClass().getName() );
}
public String generate(String strategy) {
return generatorStrategyMap.get(strategy).generate(null);
public static boolean exists(String strategy) {
return identifierGeneratorMap.containsKey(strategy.toLowerCase());
}
public static String generate(String strategy) {
strategy = strategy.toLowerCase();
return identifierGeneratorMap.get(strategy).generate(strategy);
}
}
......@@ -17,21 +17,27 @@
package org.dromara.mybatis.jpa.persistence;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Temporal;
public class FieldColumnMapper {
//class
private String fieldName;
//class field name
private String fieldName;
//class
private String fieldType;
//class field type
private String fieldType;
//table
private String columnName;
//table column name
private String columnName;
private boolean idColumn = false;
private boolean idColumn = false;
private GeneratedValue generatedValue;
private GeneratedValue generatedValue;
private Column columnAnnotation;
private Temporal temporalAnnotation;
public FieldColumnMapper() {
......@@ -84,6 +90,22 @@ public class FieldColumnMapper {
this.generatedValue = generatedValue;
}
public Column getColumnAnnotation() {
return columnAnnotation;
}
public void setColumnAnnotation(Column columnAnnotation) {
this.columnAnnotation = columnAnnotation;
}
public Temporal getTemporalAnnotation() {
return temporalAnnotation;
}
public void setTemporalAnnotation(Temporal temporalAnnotation) {
this.temporalAnnotation = temporalAnnotation;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
......@@ -97,6 +119,10 @@ public class FieldColumnMapper {
builder.append(idColumn);
builder.append(", generatedValue=");
builder.append(generatedValue);
builder.append(", columnAnnotation=");
builder.append(columnAnnotation);
builder.append(", temporalAnnotation=");
builder.append(temporalAnnotation);
builder.append("]");
return builder.toString();
}
......
......@@ -37,6 +37,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.Transient;
/**
......@@ -83,7 +84,7 @@ public class MapperMetadata <T extends JpaBaseEntity>{
public transient static ConcurrentMap<String, String>tableNameMap = new ConcurrentHashMap<String, String>();
public static IdentifierGeneratorFactory identifierGeneratorFactory=new IdentifierGeneratorFactory();
public static IdentifierGeneratorFactory identifierGeneratorFactory = new IdentifierGeneratorFactory();
/**
* getTableName and cache table name
......@@ -146,10 +147,10 @@ public class MapperMetadata <T extends JpaBaseEntity>{
public static FieldColumnMapper getIdColumn(String classSimpleName) {
List<FieldColumnMapper> listFields = fieldsMap.get(classSimpleName);
FieldColumnMapper idFieldColumnMapper=null;
FieldColumnMapper idFieldColumnMapper = null;
for (int i = 0; i < listFields.size(); i++) {
if (listFields.get(i).isIdColumn()) {
idFieldColumnMapper=listFields.get(i);
idFieldColumnMapper = listFields.get(i);
break;
}
}
......@@ -162,7 +163,7 @@ public class MapperMetadata <T extends JpaBaseEntity>{
* @return selectColumn
*/
public static String selectColumnMapper(Class<?> entityClass) {
StringBuffer selectColumn =new StringBuffer("sel_tmp_table.* ");
StringBuffer selectColumn = new StringBuffer("sel_tmp_table.* ");
int columnCount = 0;
for(FieldColumnMapper fieldColumnMapper : fieldsMap.get(entityClass.getSimpleName())) {
columnCount ++;
......@@ -217,6 +218,7 @@ public class MapperMetadata <T extends JpaBaseEntity>{
fieldColumnMapper.setFieldType(field.getType().getSimpleName());
String columnName = "";
Column columnAnnotation = (Column) field.getAnnotation(Column.class);
fieldColumnMapper.setColumnAnnotation(columnAnnotation);
if (columnAnnotation.name() != null && !columnAnnotation.name().equals("")) {
columnName = columnAnnotation.name();
} else {
......@@ -239,10 +241,15 @@ public class MapperMetadata <T extends JpaBaseEntity>{
GeneratedValue generatedValue=(GeneratedValue) field.getAnnotation(GeneratedValue.class);
fieldColumnMapper.setGeneratedValue(generatedValue);
}
if (field.isAnnotationPresent(Temporal.class)) {
Temporal temporalAnnotation = (Temporal) field.getAnnotation(Temporal.class);
fieldColumnMapper.setTemporalAnnotation(temporalAnnotation);
}
_logger.trace("FieldColumnMapper : " + fieldColumnMapper);
fieldColumnMapperList.add(fieldColumnMapper);
}
}
fieldsMap.put(entityClass.getSimpleName(), fieldColumnMapperList);
......
package org.dromara.mybatis.jpa.persistence.provider;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import org.dromara.mybatis.jpa.persistence.FieldColumnMapper;
import org.dromara.mybatis.jpa.util.BeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.persistence.TemporalType;
public class DateConverter{
private static final Logger _logger = LoggerFactory.getLogger(DateConverter.class);
public static String convert(Object entity ,FieldColumnMapper fieldColumnMapper,boolean isUpdate) {
String dateValue = "";
if(isUpdate) {
return convertDateTime(LocalDateTime.now(),fieldColumnMapper);
}
if(fieldColumnMapper.getFieldType().equalsIgnoreCase("String")) {
if(BeanUtil.get(entity, fieldColumnMapper.getFieldName()) == null
|| BeanUtil.get(entity, fieldColumnMapper.getFieldName()) == "") {
dateValue = convertDateTime(LocalDateTime.now(),fieldColumnMapper);
}else {
dateValue = BeanUtil.get(entity, fieldColumnMapper.getFieldName()).toString();
}
}else if(fieldColumnMapper.getFieldType().equalsIgnoreCase("Date")) {
Date date =(Date)BeanUtil.get(entity, fieldColumnMapper.getFieldName());
if(date == null) {
dateValue = convertDateTime(LocalDateTime.now(),fieldColumnMapper);
}else {
if(fieldColumnMapper.getTemporalAnnotation().value() == TemporalType.TIMESTAMP) {
dateValue = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}else if(fieldColumnMapper.getTemporalAnnotation().value() == TemporalType.DATE) {
dateValue = new SimpleDateFormat("yyyy-MM-dd").format(date);
}else if(fieldColumnMapper.getTemporalAnnotation().value() == TemporalType.TIME) {
dateValue = new SimpleDateFormat("HH:mm:ss").format(date);
}
}
}else if(fieldColumnMapper.getFieldType().equalsIgnoreCase("LocalDate")) {
LocalDate localDate =(LocalDate)BeanUtil.get(entity, fieldColumnMapper.getFieldName());
if(localDate == null) {
localDate = LocalDate.now();
}
dateValue = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}else if(fieldColumnMapper.getFieldType().equalsIgnoreCase("LocalTime")) {
LocalTime localTime =(LocalTime)BeanUtil.get(entity, fieldColumnMapper.getFieldName());
if(localTime == null) {
localTime = LocalTime.now();
}
dateValue = localTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
}else if(fieldColumnMapper.getFieldType().equalsIgnoreCase("LocalDateTime")) {
LocalDateTime localDateTime =(LocalDateTime)BeanUtil.get(entity, fieldColumnMapper.getFieldName());
if(localDateTime == null) {
localDateTime = LocalDateTime.now();
}
dateValue = convertDateTime(localDateTime,fieldColumnMapper);
}
_logger.debug("Date Value {}" ,dateValue);
return dateValue;
}
public static String convertDateTime(LocalDateTime localDateTime ,FieldColumnMapper fieldColumnMapper) {
if(fieldColumnMapper.getTemporalAnnotation().value() == TemporalType.TIMESTAMP) {
return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}else if(fieldColumnMapper.getTemporalAnnotation().value() == TemporalType.DATE) {
return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}else{
return localDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
}
}
}
......@@ -24,6 +24,7 @@ import java.util.List;
import org.apache.ibatis.jdbc.SQL;
import org.dromara.mybatis.jpa.id.IdStrategy;
import org.dromara.mybatis.jpa.id.IdentifierGeneratorFactory;
import org.dromara.mybatis.jpa.persistence.FieldColumnMapper;
import org.dromara.mybatis.jpa.persistence.JpaBaseEntity;
import org.dromara.mybatis.jpa.persistence.MapperMetadata;
......@@ -53,47 +54,50 @@ public class InsertProvider <T extends JpaBaseEntity>{
SQL sql = new SQL().INSERT_INTO(MapperMetadata.getTableName(entity.getClass()));
for (int i = 0; i < listFields.size(); i++) {
FieldColumnMapper fieldColumnMapper=listFields.get(i);
FieldColumnMapper fieldColumnMapper = listFields.get(i);
_logger.trace("fieldColumnMapper {} ",fieldColumnMapper);
if(
(
fieldColumnMapper.getFieldType().equalsIgnoreCase("String")
||fieldColumnMapper.getFieldType().startsWith("byte")
)
&& BeanUtil.getValue(entity, fieldColumnMapper.getFieldName())==null
&& fieldColumnMapper.getGeneratedValue() == null
&& !fieldColumnMapper.isIdColumn()) {
//skip null field value
_logger.trace("skip field value is null ");
}else {
//have @id or @GeneratedValue and (value is null or eq "")
if((fieldColumnMapper.isIdColumn() || fieldColumnMapper.getGeneratedValue() != null)
&& (
BeanUtil.get(entity, fieldColumnMapper.getFieldName()) == null
|| BeanUtil.get(entity, fieldColumnMapper.getFieldName()) == ""
)) {
GeneratedValue generatedValue = listFields.get(i).getGeneratedValue();
if(generatedValue == null || generatedValue.strategy() == GenerationType.AUTO) {
String generatorId = "";
if(generatedValue == null ) {
generatorId = generatedValue(IdStrategy.DEFAULT);
}else if(MapperMetadata.identifierGeneratorFactory.getGeneratorStrategyMap()
.containsKey(generatedValue.generator().toLowerCase())) {
generatorId = generatedValue(generatedValue.generator().toLowerCase());
}else {
generatorId = generatedValue(IdStrategy.DEFAULT);
if(fieldColumnMapper.getColumnAnnotation().insertable()) {
if(
(
fieldColumnMapper.getFieldType().equalsIgnoreCase("String")
||fieldColumnMapper.getFieldType().startsWith("byte")
)
&& BeanUtil.getValue(entity, fieldColumnMapper.getFieldName())==null
&& fieldColumnMapper.getGeneratedValue() == null
&& !fieldColumnMapper.isIdColumn()) {
//skip null field value
_logger.trace("skip field value is null ");
}else {
if(fieldColumnMapper.getGeneratedValue() != null && fieldColumnMapper.getTemporalAnnotation() != null) {
sql.VALUES(fieldColumnMapper.getColumnName(),"'" + DateConverter.convert(entity, fieldColumnMapper,false) + "'");
}else if((fieldColumnMapper.isIdColumn() || fieldColumnMapper.getGeneratedValue() != null)
&& (
BeanUtil.get(entity, fieldColumnMapper.getFieldName()) == null
|| BeanUtil.get(entity, fieldColumnMapper.getFieldName()) == ""
)) {
//have @id or @GeneratedValue and (value is null or eq "")
GeneratedValue generatedValue = listFields.get(i).getGeneratedValue();
if(generatedValue == null || generatedValue.strategy() == GenerationType.AUTO) {
String genValue = "";
if(generatedValue == null ) {
genValue = IdentifierGeneratorFactory.generate(IdStrategy.DEFAULT);
}else if(IdentifierGeneratorFactory.exists(generatedValue.generator())) {
genValue = IdentifierGeneratorFactory.generate(generatedValue.generator());
}else {
genValue = IdentifierGeneratorFactory.generate(IdStrategy.DEFAULT);
}
BeanUtil.set(entity, fieldColumnMapper.getFieldName(),genValue);
sql.VALUES(fieldColumnMapper.getColumnName(),"#{" + fieldColumnMapper.getFieldName() + "}");
}else if(generatedValue.strategy()==GenerationType.SEQUENCE){
sql.VALUES(fieldColumnMapper.getColumnName(),generatedValue.generator()+".nextval");
}else if(generatedValue.strategy()==GenerationType.IDENTITY){
//skip
}else if(generatedValue.strategy()==GenerationType.TABLE){
//skip
}
BeanUtil.set(entity, fieldColumnMapper.getFieldName(),generatorId);
}else {
sql.VALUES(fieldColumnMapper.getColumnName(),"#{" + fieldColumnMapper.getFieldName() + "}");
}else if(generatedValue.strategy()==GenerationType.SEQUENCE){
sql.VALUES(fieldColumnMapper.getColumnName(),generatedValue.generator()+".nextval");
}else if(generatedValue.strategy()==GenerationType.IDENTITY){
//skip
}else if(generatedValue.strategy()==GenerationType.TABLE){
//skip
}
}else {
sql.VALUES(fieldColumnMapper.getColumnName(),"#{" + fieldColumnMapper.getFieldName() + "}");
}
}
}
......@@ -101,8 +105,4 @@ public class InsertProvider <T extends JpaBaseEntity>{
return sql.toString();
}
private String generatedValue(String strategy) {
return MapperMetadata.identifierGeneratorFactory.generate(strategy);
}
}
......@@ -60,15 +60,22 @@ public class UpdateProvider <T extends JpaBaseEntity>{
(fieldColumnMapper.getFieldType().equalsIgnoreCase("String")
||fieldColumnMapper.getFieldType().startsWith("byte")
)
&&BeanUtil.getValue(entity, fieldColumnMapper.getFieldName())==null) {
&& BeanUtil.getValue(entity, fieldColumnMapper.getFieldName())== null
&& fieldColumnMapper.getGeneratedValue() == null) {
//skip null field value
_logger.trace("skip field value is null ");
}else {
sql.SET(fieldColumnMapper.getColumnName() + " = #{" + fieldColumnMapper.getFieldName() + "}");
if(fieldColumnMapper.getColumnAnnotation().updatable()) {
if(fieldColumnMapper.getGeneratedValue() != null && fieldColumnMapper.getTemporalAnnotation() != null) {
sql.SET(fieldColumnMapper.getColumnName() + " = '" + DateConverter.convert(entity, fieldColumnMapper,true) + "'");
}else {
sql.SET(fieldColumnMapper.getColumnName() + " = #{" + fieldColumnMapper.getFieldName() + "}");
}
}
}
}
FieldColumnMapper idFieldColumnMapper=MapperMetadata.getIdColumn(entity.getClass().getSimpleName());
FieldColumnMapper idFieldColumnMapper = MapperMetadata.getIdColumn(entity.getClass().getSimpleName());
sql.WHERE(idFieldColumnMapper.getColumnName() + " = #{" + idFieldColumnMapper.getFieldName() + "}");
_logger.trace("Update SQL : \n{}" , sql);
return sql.toString();
......
......@@ -17,6 +17,7 @@
package org.dromara.mybatis.jpa.test.entity;
import java.io.Serializable;
import java.util.Date;
import org.dromara.mybatis.jpa.persistence.JpaBaseEntity;
......@@ -25,6 +26,8 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
/*
ID varchar(40) not null,
......@@ -68,6 +71,11 @@ public class Students extends JpaBaseEntity implements Serializable {
private String stdClass;
@Column
private byte[] images;
@Column(insertable = false)
@GeneratedValue
@Temporal(TemporalType.TIMESTAMP)
private Date modifyDate;
public Students() {
super();
......@@ -141,6 +149,14 @@ public class Students extends JpaBaseEntity implements Serializable {
this.images = images;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
@Override
public String toString() {
return "Students [id=" + id + ", stdNo=" + stdNo + ", stdName=" + stdName + ", stdGender=" + stdGender
......
......@@ -97,7 +97,7 @@
<context:component-scan base-package="org.dromara.mybatis.jpa.test.dao.service" />
<bean class ="org.dromara.mybatis.jpa.id.IdentifierGeneratorFactory">
<property name="generatorStrategyMap" >
<property name="identifierGeneratorMap" >
<map>
<entry key="serial" >
<bean class="org.dromara.mybatis.jpa.id.SerialGenerator">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册