diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Column.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Column.java index 9916c62b..fb29d793 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Column.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Column.java @@ -30,12 +30,12 @@ public @interface Column { /** * update 的时候自动赋值,这个值会直接被拼接到 sql 而不通过参数设置 */ - String update() default ""; + String onUpdateValue() default ""; /** * insert 的时候默认值,这个值会直接被拼接到 sql 而不通过参数设置 */ - String insert() default ""; + String onInsertValue() default ""; /** * 是否忽略该字段,可能只是业务字段,而非数据库对应字段 diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/CommonsDialectImpl.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/CommonsDialectImpl.java index 089fae15..9f22081e 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/CommonsDialectImpl.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/CommonsDialectImpl.java @@ -25,6 +25,7 @@ import com.mybatisflex.core.util.StringUtil; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.StringJoiner; /** * 通用的方言设计,其他方言可以继承于当前 CommonsDialectImpl @@ -350,11 +351,26 @@ public class CommonsDialectImpl implements IDialect { public String forInsertEntity(TableInfo tableInfo, Object entity) { StringBuilder sql = new StringBuilder(); sql.append("INSERT INTO ").append(wrap(tableInfo.getTableName())); + + String[] insertColumns = tableInfo.obtainInsertColumns(); - sql.append("(").append(StringUtil.join(",", insertColumns)).append(")"); - sql.append(" VALUES "); - sql.append(buildQuestion(insertColumns.length, true)); - return sql.toString(); + Map onInsertColumns = tableInfo.getOnInsertColumns(); + + StringJoiner sqlFields = new StringJoiner(", "); + StringJoiner sqlValues = new StringJoiner(", "); + + for (String insertColumn : insertColumns) { + sqlFields.add(insertColumn); + if (onInsertColumns != null && onInsertColumns.containsKey(insertColumn)) { + sqlValues.add(onInsertColumns.get(insertColumn)); + } else { + sqlValues.add("?"); + } + } + + return sql.append("(").append(sqlFields).append(")") + .append(" VALUES ") + .append("(").append(sqlValues).append(")").toString(); } @Override @@ -365,12 +381,22 @@ public class CommonsDialectImpl implements IDialect { sql.append("(").append(StringUtil.join(",", insertColumns)).append(")"); sql.append(" VALUES "); + Map onInsertColumns = tableInfo.getOnInsertColumns(); for (int i = 0; i < entities.size(); i++) { - sql.append(buildQuestion(insertColumns.length, true)); + StringJoiner stringJoiner = new StringJoiner("(", ", ", ")"); + for (String insertColumn : insertColumns) { + if (onInsertColumns != null && onInsertColumns.containsKey(insertColumn)) { + stringJoiner.add(onInsertColumns.get(insertColumn)); + } else { + stringJoiner.add("?"); + } + } + sql.append(stringJoiner); if (i != entities.size() - 1) { sql.append(", "); } } + return sql.toString(); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java index b9c77e45..1001eb3c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java @@ -40,12 +40,29 @@ public class TableInfo { private boolean useCached = false; private boolean camelToUnderline = true; + //逻辑删除数据库列名 + private String logicDeleteColumn; - private String[] columns = new String[0]; // 所有的字段,但除了主键的列 - private String[] primaryKeys = new String[0]; //主键字段 + //乐观锁字段 + private String versionColumn; + + //数据插入时,默认插入数据字段 + private Map onInsertColumns; + + //数据更新时,默认更新内容的字段 + private Map onUpdateColumns; + + //大字段列 + private String[] largeColumns = new String[0]; + + // 所有的字段,但除了主键的列 + private String[] columns = new String[0]; + + //主键字段 + private String[] primaryKeys = new String[0]; //在插入数据的时候,支持主动插入的主键字段 - //排除主键为 auto 和 before 为 false 的主键字段 + //通过自定义生成器生成 或者 Sequence 在 before 生成的时候,是需要主动插入数据的 private String[] insertPrimaryKeys; private List columnInfoList; @@ -103,6 +120,54 @@ public class TableInfo { this.camelToUnderline = camelToUnderline; } + public String getLogicDeleteColumn() { + return logicDeleteColumn; + } + + public void setLogicDeleteColumn(String logicDeleteColumn) { + this.logicDeleteColumn = logicDeleteColumn; + } + + public String getVersionColumn() { + return versionColumn; + } + + public void setVersionColumn(String versionColumn) { + this.versionColumn = versionColumn; + } + + public Map getOnInsertColumns() { + return onInsertColumns; + } + + public void setOnInsertColumns(Map onInsertColumns) { + this.onInsertColumns = onInsertColumns; + } + + public Map getOnUpdateColumns() { + return onUpdateColumns; + } + + public void setOnUpdateColumns(Map onUpdateColumns) { + this.onUpdateColumns = onUpdateColumns; + } + + public String[] getLargeColumns() { + return largeColumns; + } + + public void setLargeColumns(String[] largeColumns) { + this.largeColumns = largeColumns; + } + + public String[] getInsertPrimaryKeys() { + return insertPrimaryKeys; + } + + public void setInsertPrimaryKeys(String[] insertPrimaryKeys) { + this.insertPrimaryKeys = insertPrimaryKeys; + } + public Reflector getReflector() { return reflector; } @@ -191,13 +256,15 @@ public class TableInfo { public Object[] obtainInsertValues(Object entity) { MetaObject metaObject = EntityMetaObject.forObject(entity, reflectorFactory); String[] insertColumns = obtainInsertColumns(); - Object[] values = new Object[insertColumns.length]; - for (int i = 0; i < insertColumns.length; i++) { - Object value = getColumnValue(metaObject, insertColumns[i]); - values[i] = value; - } - return values; + List values = new ArrayList<>(insertColumns.length); + for (String insertColumn : insertColumns) { + if (onInsertColumns == null || !onInsertColumns.containsKey(insertColumn)) { + Object value = getColumnValue(metaObject, insertColumn); + values.add(value); + } + } + return values.toArray(); } @@ -366,6 +433,7 @@ public class TableInfo { /** * 通过 row 实例类转换为一个 entity + * * @return entity */ public T newInstanceByRow(Row row) { diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfos.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfos.java index d6d254b5..d44e3b30 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfos.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfos.java @@ -19,6 +19,7 @@ import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Table; import com.mybatisflex.core.FlexConsts; +import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.util.ClassUtil; import com.mybatisflex.core.util.CollectionUtil; import com.mybatisflex.core.util.StringUtil; @@ -37,6 +38,10 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class TableInfos { + + /** + * 支持映射到数据库的数据类型 + */ private static final Set> defaultSupportColumnTypes = CollectionUtil.newHashSet( int.class, Integer.class, short.class, Short.class, @@ -106,6 +111,19 @@ public class TableInfos { Field idField = null; + String logicDeleteColumn = null; + String versionColumn = null; + + //数据插入时,默认插入数据字段 + Map onInsertColumns = new HashMap<>(); + + //数据更新时,默认更新内容的字段 + Map onUpdateColumns = new HashMap<>(); + + //大字段列 + Set largeColumns = new LinkedHashSet<>(); + + List entityFields = ClassUtil.getAllFields(entityClass); for (Field field : entityFields) { @@ -119,10 +137,44 @@ public class TableInfos { continue; // ignore } + //列名 String columnName = column != null && StringUtil.isNotBlank(column.value()) ? column.value() : (tableInfo.isCamelToUnderline() ? StringUtil.camelToUnderline(field.getName()) : field.getName()); + //逻辑删除字段 + if (column != null && column.isLogicDelete()) { + if (logicDeleteColumn == null) { + logicDeleteColumn = columnName; + } else { + throw FlexExceptions.wrap("The logic delete column of entity[%s] must be less then 2.", entityClass.getName()); + } + } + + //乐观锁版本字段 + if (column != null && column.version()) { + if (versionColumn == null) { + versionColumn = columnName; + } else { + throw FlexExceptions.wrap("The version column of entity[%s] must be less then 2.", entityClass.getName()); + } + } + + if (column != null && StringUtil.isNotBlank(column.onInsertValue())) { + onInsertColumns.put(columnName, column.onInsertValue().trim()); + } + + + if (column != null && StringUtil.isNotBlank(column.onUpdateValue())) { + onUpdateColumns.put(columnName, column.onUpdateValue().trim()); + } + + + if (column != null && column.isLarge()) { + largeColumns.add(columnName); + } + + Id id = field.getAnnotation(Id.class); ColumnInfo columnInfo; if (id != null) { @@ -158,9 +210,25 @@ public class TableInfos { } } + tableInfo.setLogicDeleteColumn(logicDeleteColumn); + tableInfo.setVersionColumn(versionColumn); + + if (!onInsertColumns.isEmpty()) { + tableInfo.setOnInsertColumns(onInsertColumns); + } + + if (!onUpdateColumns.isEmpty()) { + tableInfo.setOnUpdateColumns(onUpdateColumns); + } + + if (!largeColumns.isEmpty()) { + tableInfo.setLargeColumns(largeColumns.toArray(new String[0])); + } + tableInfo.setColumnInfoList(columnInfoList); tableInfo.setPrimaryKeyList(idInfos); + return tableInfo; } } diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/test/Article.java b/mybatis-flex-core/src/test/java/com/mybatisflex/test/Article.java index aa3f02b2..241b6fe9 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/test/Article.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/test/Article.java @@ -20,10 +20,10 @@ public class Article { @Column(isLarge = true) private String content; - @Column(insert = "now()") + @Column(onInsertValue = "now()") private Date created; - @Column(update = "now()") + @Column(onUpdateValue = "now()") private Date modified; }