diff --git a/docs/zh/base/active-record.md b/docs/zh/base/active-record.md index a213ff21..09fbf5b3 100644 --- a/docs/zh/base/active-record.md +++ b/docs/zh/base/active-record.md @@ -201,3 +201,20 @@ User.create() ``` > 获取更多关于 `Fields Query` 的信息,请点击 [这里](./relations-query.md#方案-2field-query) + +## 回调方法 + +有些情况下,我们在操作完数据库后,还需要继续使用实体类的内容,例如:获取插入数据后返回的主键。此时这些返回值为 `boolean` 的方法就不满足我们的需求了, +应该使用 `xxxOpt` 方法,在操作数据库执行成功之后返回 `Optional.of(this)`,执行失败返回 `Optional.empty()`。这样就可以进行链式的调用了。 + +```java +// 插入成功之后返回主键信息 +Account.create() + .setUserName("张三") + .setAge(18) + .setBirthday(new Date()) + .saveCallback() + .orElseThrow(RuntimeException::new) // 保存失败抛出异常 + .getId(); +``` + diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/Generator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/Generator.java index dc64efe1..45a0dda9 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/Generator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/Generator.java @@ -122,4 +122,31 @@ public class Generator { } } + public DataSource getDataSource() { + return dataSource; + } + + public Generator setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + return this; + } + + public GlobalConfig getGlobalConfig() { + return globalConfig; + } + + public Generator setGlobalConfig(GlobalConfig globalConfig) { + this.globalConfig = globalConfig; + return this; + } + + public IDialect getDialect() { + return dialect; + } + + public Generator setDialect(IDialect dialect) { + this.dialect = dialect; + return this; + } + } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/ColumnConfig.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/ColumnConfig.java index dfc1f7a7..f89afa77 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/ColumnConfig.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/ColumnConfig.java @@ -24,8 +24,11 @@ import java.io.Serializable; /** * 表字段的单独设置。 */ +@SuppressWarnings({"rawtypes", "UnusedReturnValue", "unused"}) public class ColumnConfig implements Serializable { + private static final long serialVersionUID = -1511605303951623381L; + /** * 字段名称。 */ @@ -56,6 +59,11 @@ public class ColumnConfig implements Serializable { */ private Boolean version; + /** + * 是否是租户 ID。 + */ + private Boolean tenantId; + /** * 配置的 jdbcType。 */ @@ -82,7 +90,7 @@ public class ColumnConfig implements Serializable { /** * 脱敏方式。 */ - private String mask; + private String maskType; /** * 字段是否为主键。 @@ -104,139 +112,235 @@ public class ColumnConfig implements Serializable { */ private Boolean keyBefore; - /** - * 是否是租户 ID。 - */ - private Boolean tenantId; - - public String getColumnName() { - return columnName; + public static ColumnConfig create() { + return new ColumnConfig(); } - public void setColumnName(String columnName) { + public String getColumnName() { + return this.columnName; + } + + public ColumnConfig setColumnName(String columnName) { this.columnName = columnName; + return this; } public String getOnInsertValue() { - return onInsertValue; + return this.onInsertValue; } - public void setOnInsertValue(String onInsertValue) { + public ColumnConfig setOnInsertValue(String onInsertValue) { this.onInsertValue = onInsertValue; + return this; } public String getOnUpdateValue() { - return onUpdateValue; + return this.onUpdateValue; } - public void setOnUpdateValue(String onUpdateValue) { + public ColumnConfig setOnUpdateValue(String onUpdateValue) { this.onUpdateValue = onUpdateValue; + return this; } public Boolean getLarge() { - return isLarge; + return this.isLarge; } - public void setLarge(Boolean large) { - isLarge = large; + public ColumnConfig setLarge(Boolean large) { + this.isLarge = large; + return this; } public Boolean getLogicDelete() { - return isLogicDelete; + return this.isLogicDelete; } - public void setLogicDelete(Boolean logicDelete) { - isLogicDelete = logicDelete; + public ColumnConfig setLogicDelete(Boolean logicDelete) { + this.isLogicDelete = logicDelete; + return this; } public Boolean getVersion() { - return version; + return this.version; } - public void setVersion(Boolean version) { + public ColumnConfig setVersion(Boolean version) { this.version = version; - } - - public JdbcType getJdbcType() { - return jdbcType; - } - - public void setJdbcType(JdbcType jdbcType) { - this.jdbcType = jdbcType; - } - - public Class getTypeHandler() { - return typeHandler; - } - - public void setTypeHandler(Class typeHandler) { - this.typeHandler = typeHandler; - } - - public String getMask() { - return mask; - } - - public void setMask(String mask) { - this.mask = mask; - } - - public boolean isPrimaryKey() { - return isPrimaryKey; - } - - public void setPrimaryKey(boolean primaryKey) { - isPrimaryKey = primaryKey; - } - - public KeyType getKeyType() { - return keyType; - } - - public void setKeyType(KeyType keyType) { - this.keyType = keyType; - } - - public String getKeyValue() { - return keyValue; - } - - public void setKeyValue(String keyValue) { - this.keyValue = keyValue; - } - - public Boolean getKeyBefore() { - return keyBefore; - } - - public void setKeyBefore(Boolean keyBefore) { - this.keyBefore = keyBefore; + return this; } public Boolean getTenantId() { - return tenantId; + return this.tenantId; } - public void setTenantId(Boolean tenantId) { + public ColumnConfig setTenantId(Boolean tenantId) { this.tenantId = tenantId; + return this; + } + + public JdbcType getJdbcType() { + return this.jdbcType; + } + + public ColumnConfig setJdbcType(JdbcType jdbcType) { + this.jdbcType = jdbcType; + return this; } public String getPropertyType() { - return propertyType; + return this.propertyType; } - /** - * 原始类型直接写类型名称,例:int/long/float/double/boolean,对象类型请写对应类的全限定名,例:java.lang.String - */ - public void setPropertyType(String propertyType) { + public ColumnConfig setPropertyType(String propertyType) { this.propertyType = propertyType; + return this; } public String getPropertyDefaultValue() { - return propertyDefaultValue; + return this.propertyDefaultValue; } - public void setPropertyDefaultValue(String propertyDefaultValue) { + public ColumnConfig setPropertyDefaultValue(String propertyDefaultValue) { this.propertyDefaultValue = propertyDefaultValue; + return this; } + + public Class getTypeHandler() { + return this.typeHandler; + } + + public ColumnConfig setTypeHandler(Class typeHandler) { + this.typeHandler = typeHandler; + return this; + } + + public String getMaskType() { + return this.maskType; + } + + public ColumnConfig setMaskType(String maskType) { + this.maskType = maskType; + return this; + } + + public boolean isPrimaryKey() { + return this.isPrimaryKey; + } + + public ColumnConfig setPrimaryKey(boolean primaryKey) { + this.isPrimaryKey = primaryKey; + return this; + } + + public KeyType getKeyType() { + return this.keyType; + } + + public ColumnConfig setKeyType(KeyType keyType) { + this.keyType = keyType; + return this; + } + + public String getKeyValue() { + return this.keyValue; + } + + public ColumnConfig setKeyValue(String keyValue) { + this.keyValue = keyValue; + return this; + } + + public Boolean getKeyBefore() { + return this.keyBefore; + } + + public ColumnConfig setKeyBefore(Boolean keyBefore) { + this.keyBefore = keyBefore; + return this; + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + + private final ColumnConfig columnConfig; + + private Builder() { + this.columnConfig = new ColumnConfig(); + } + + public Builder columnName(String columnName) { + this.columnConfig.setColumnName(columnName); + return this; + } + + public Builder onInsertValue(String onInsertValue) { + this.columnConfig.setOnInsertValue(onInsertValue); + return this; + } + + public Builder onUpdateValue(String onUpdateValue) { + this.columnConfig.setOnUpdateValue(onUpdateValue); + return this; + } + + public Builder version(Boolean version) { + this.columnConfig.setVersion(version); + return this; + } + + public Builder tenantId(Boolean tenantId) { + this.columnConfig.setTenantId(tenantId); + return this; + } + + public Builder jdbcType(JdbcType jdbcType) { + this.columnConfig.setJdbcType(jdbcType); + return this; + } + + public Builder propertyType(String propertyType) { + this.columnConfig.setPropertyType(propertyType); + return this; + } + + public Builder propertyDefaultValue(String propertyDefaultValue) { + this.columnConfig.setPropertyDefaultValue(propertyDefaultValue); + return this; + } + + public Builder typeHandler(Class typeHandler) { + this.columnConfig.setTypeHandler(typeHandler); + return this; + } + + public Builder maskType(String maskType) { + this.columnConfig.setMaskType(maskType); + return this; + } + + public Builder keyType(KeyType keyType) { + this.columnConfig.setKeyType(keyType); + return this; + } + + public Builder keyValue(String keyValue) { + this.columnConfig.setKeyValue(keyValue); + return this; + } + + public Builder keyBefore(Boolean keyBefore) { + this.columnConfig.setKeyBefore(keyBefore); + return this; + } + + public ColumnConfig build() { + return this.columnConfig; + } + + } + } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/StrategyConfig.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/StrategyConfig.java index d27b6ea1..cf7b3094 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/StrategyConfig.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/StrategyConfig.java @@ -87,6 +87,7 @@ public class StrategyConfig { public Set getIgnoreColumns() { return ignoreColumns; } + /** * 设置需要忽略的列 全局配置。 */ @@ -121,7 +122,8 @@ public class StrategyConfig { * 获取表配置。 */ public TableConfig getTableConfig(String tableName) { - return tableConfigMap == null ? null : tableConfigMap.get(tableName); + TableConfig tableConfig = tableConfigMap == null ? null : tableConfigMap.get(tableName); + return tableConfig != null ? tableConfig : tableConfigMap.get(TableConfig.ALL_TABLES); } /** @@ -190,7 +192,7 @@ public class StrategyConfig { setTableConfig(tableConfig); } - tableConfig.addColumnConfig(columnConfig); + tableConfig.setColumnConfig(columnConfig); return this; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/TableConfig.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/TableConfig.java index 707d5ad5..2354122a 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/TableConfig.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/config/TableConfig.java @@ -25,18 +25,21 @@ import java.util.Map; /** * 表的单独设置。 */ +@SuppressWarnings({"unused", "UnusedReturnValue"}) public class TableConfig { - /** - * 表名。 - */ - private String tableName; + public static final String ALL_TABLES = "*"; /** * 数据库的 schema(模式)。 */ private String schema; + /** + * 表名。 + */ + private String tableName = ALL_TABLES; + /** * 默认为 驼峰属性 转换为 下划线字段。 */ @@ -57,89 +60,160 @@ public class TableConfig { */ private Class setListenerClass; - /** - * 对应列的配置。 - */ - private Map columnConfigMap; - /** * 是否开启 Mapper 生成。 */ private Boolean mapperGenerateEnable = Boolean.TRUE; - public String getTableName() { - return tableName; - } + /** + * 对应列的配置。 + */ + private Map columnConfigMap; - public void setTableName(String tableName) { - this.tableName = tableName; + public static TableConfig create() { + return new TableConfig(); } public String getSchema() { - return schema; + return this.schema; } - public void setSchema(String schema) { + public TableConfig setSchema(String schema) { this.schema = schema; + return this; + } + + public String getTableName() { + return this.tableName; + } + + public TableConfig setTableName(String tableName) { + this.tableName = tableName; + return this; } public Boolean getCamelToUnderline() { - return camelToUnderline; + return this.camelToUnderline; } - public void setCamelToUnderline(Boolean camelToUnderline) { + public TableConfig setCamelToUnderline(Boolean camelToUnderline) { this.camelToUnderline = camelToUnderline; + return this; } public Class getInsertListenerClass() { - return insertListenerClass; + return this.insertListenerClass; } - public void setInsertListenerClass(Class insertListenerClass) { + public TableConfig setInsertListenerClass(Class insertListenerClass) { this.insertListenerClass = insertListenerClass; + return this; } public Class getUpdateListenerClass() { - return updateListenerClass; + return this.updateListenerClass; } - public void setUpdateListenerClass(Class updateListenerClass) { + public TableConfig setUpdateListenerClass(Class updateListenerClass) { this.updateListenerClass = updateListenerClass; + return this; } public Class getSetListenerClass() { - return setListenerClass; + return this.setListenerClass; } - public void setSetListenerClass(Class setListenerClass) { + public TableConfig setSetListenerClass(Class setListenerClass) { this.setListenerClass = setListenerClass; - } - - public Map getColumnConfigMap() { - return columnConfigMap; - } - - public void setColumnConfigMap(Map columnConfigMap) { - this.columnConfigMap = columnConfigMap; + return this; } public Boolean getMapperGenerateEnable() { - return mapperGenerateEnable; + return this.mapperGenerateEnable; } - public void setMapperGenerateEnable(Boolean mapperGenerateEnable) { + public TableConfig setMapperGenerateEnable(Boolean mapperGenerateEnable) { this.mapperGenerateEnable = mapperGenerateEnable; + return this; } - public void addColumnConfig(ColumnConfig columnConfig) { - if (columnConfigMap == null) { - columnConfigMap = new HashMap<>(); + public Map getColumnConfigMap() { + return this.columnConfigMap; + } + + public TableConfig setColumnConfigMap(Map columnConfigMap) { + this.columnConfigMap = columnConfigMap; + return this; + } + + public TableConfig setColumnConfig(ColumnConfig columnConfig) { + if (this.columnConfigMap == null) { + this.columnConfigMap = new HashMap<>(); } - columnConfigMap.put(columnConfig.getColumnName(), columnConfig); + this.columnConfigMap.put(columnConfig.getColumnName(), columnConfig); + return this; } - public ColumnConfig getColumnConfig(String columnName) { - return columnConfigMap == null ? null : columnConfigMap.get(columnName); + protected ColumnConfig getColumnConfig(String columnName) { + return this.columnConfigMap == null ? null : this.columnConfigMap.get(columnName); + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + + private final TableConfig tableConfig; + + private Builder() { + this.tableConfig = new TableConfig(); + } + + public Builder schema(String schema) { + this.tableConfig.setSchema(schema); + return this; + } + + public Builder tableName(String tableName) { + this.tableConfig.setTableName(tableName); + return this; + } + + public Builder camelToUnderline(Boolean camelToUnderline) { + this.tableConfig.setCamelToUnderline(camelToUnderline); + return this; + } + + public Builder insertListenerClass(Class insertListenerClass) { + this.tableConfig.setInsertListenerClass(insertListenerClass); + return this; + } + + public Builder updateListenerClass(Class updateListenerClass) { + this.tableConfig.setUpdateListenerClass(updateListenerClass); + return this; + } + + public Builder setListenerClass(Class setListenerClass) { + this.tableConfig.setSetListenerClass(setListenerClass); + return this; + } + + public Builder mapperGenerateEnable(Boolean mapperGenerateEnable) { + this.tableConfig.setMapperGenerateEnable(mapperGenerateEnable); + return this; + } + + public Builder columnConfig(ColumnConfig columnConfigMap) { + this.tableConfig.setColumnConfig(columnConfigMap); + return this; + } + + public TableConfig build() { + return this.tableConfig; + } + } } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/entity/Column.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/entity/Column.java index e44136b2..7129d518 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/entity/Column.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/entity/Column.java @@ -295,8 +295,8 @@ public class Column { } //@ColumnMask 注解 - if (columnConfig.getMask() != null) { - annotations.append("@ColumnMask(\"").append(columnConfig.getMask()).append("\")"); + if (columnConfig.getMaskType() != null) { + annotations.append("@ColumnMask(\"").append(columnConfig.getMaskType()).append("\")"); } return annotations.toString(); @@ -324,7 +324,7 @@ public class Column { if (columnConfig.getPropertyType() != null) { addImportClass(importClasses, columnConfig.getPropertyType()); } - if (columnConfig.getMask() != null) { + if (columnConfig.getMaskType() != null) { addImportClass(importClasses, ColumnMask.class.getName()); } diff --git a/mybatis-flex-codegen/src/test/java/com/mybatisflex/codegen/test/GeneratorTest.java b/mybatis-flex-codegen/src/test/java/com/mybatisflex/codegen/test/GeneratorTest.java index 3bd55f87..4808532c 100644 --- a/mybatis-flex-codegen/src/test/java/com/mybatisflex/codegen/test/GeneratorTest.java +++ b/mybatis-flex-codegen/src/test/java/com/mybatisflex/codegen/test/GeneratorTest.java @@ -23,6 +23,7 @@ import com.mybatisflex.codegen.config.TableConfig; import com.mybatisflex.codegen.config.TableDefConfig; import com.mybatisflex.codegen.constant.TemplateConst; import com.zaxxer.hikari.HikariDataSource; +import org.junit.Test; import java.util.function.UnaryOperator; @@ -149,7 +150,7 @@ public class GeneratorTest { generator.generate(); } -// @Test + // @Test public void testCodeGen3() { //配置数据源 HikariDataSource dataSource = new HikariDataSource(); @@ -189,7 +190,7 @@ public class GeneratorTest { TableConfig tableConfig = new TableConfig(); tableConfig.setTableName("sys_user"); - tableConfig.addColumnConfig(columnConfig); + tableConfig.setColumnConfig(columnConfig); ColumnConfig logicDelete = new ColumnConfig(); logicDelete.setColumnName("del_flag"); @@ -225,7 +226,7 @@ public class GeneratorTest { return globalConfig; } -// @Test + // @Test public void testCodeGen4() { // 配置数据源 HikariDataSource dataSource = new HikariDataSource(); @@ -276,4 +277,72 @@ public class GeneratorTest { generator.generate(); } + @Test + public void testCodeGen5() { + // 配置数据源 + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8"); + dataSource.setUsername("root"); + dataSource.setPassword("12345678"); + + GlobalConfig globalConfig = new GlobalConfig(); + + // 用户信息表,用于存放用户信息。 -> 用户信息 + UnaryOperator tableFormat = (e) -> e.split(",")[0].replace("表", ""); + + // 设置注解生成配置 + globalConfig.getJavadocConfig() + .setAuthor("王帅") + .setTableCommentFormat(tableFormat); + + // 设置生成文件目录和根包 + globalConfig.getPackageConfig() + .setSourceDir(System.getProperty("user.dir") + "/src/test/java") + .setMapperXmlPath(System.getProperty("user.dir") + "/src/test/resources/mapper") + .setBasePackage("com.test"); + + // 设置表前缀和只生成哪些表 + globalConfig.getStrategyConfig() + .setTablePrefix("sys_") + .setGenerateTable("sys_user", "sys_role"); + + // 全局表配置 + TableConfig tableConfig = TableConfig.builder() + .camelToUnderline(false) + .mapperGenerateEnable(false) + .build(); + + // sys_user 字段单独配置 + ColumnConfig userColumnConfig = ColumnConfig.create() + .setColumnName("update_time") + .setOnUpdateValue("NOW()"); + + // sys_user 表单独配置 + TableConfig userTableConfig = TableConfig.create() + .setTableName("sys_user") + .setColumnConfig(userColumnConfig); + + // 全局字段配置 + ColumnConfig columnConfig = ColumnConfig.builder() + .columnName("create_time") + .onInsertValue("NOW()") + .build(); + + globalConfig.getStrategyConfig() + .setTableConfig(tableConfig) + .setTableConfig(userTableConfig) + .setColumnConfig(columnConfig); + + // 配置生成 entity + globalConfig.enableEntity() + .setOverwriteEnable(true) + .setWithLombok(true); + + //通过 datasource 和 globalConfig 创建代码生成器 + Generator generator = new Generator(dataSource, globalConfig); + + //开始生成代码 + generator.generate(); + } + } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/MapperModel.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/MapperModel.java index fe190c32..6539f4aa 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/MapperModel.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/MapperModel.java @@ -71,27 +71,17 @@ public interface MapperModel { return save(true); } - /** - * 保存数据并返回 entity 本身,并设置是否忽略 {@code null} 值。 + * 保存数据(自动忽略 {@code null} 值),结果使用 {@link Optional} + * 返回源对象回调,保存成功返回 {@code Optional.of(this)},保存失败返回 + * {@code Optional.empty()}。 * - * @return entity 本身 + * @return {@link Optional} 链式调用 */ - default T saveAndReturnSelf() { - return saveAndReturnSelf(true); + default Optional saveOpt() { + return saveOpt(true); } - - /** - * 保存数据并返回保存成功的 id,并设置是否忽略 {@code null} 值。 - * - * @return id 值 - */ - default R saveAndReturnId() { - return saveAndReturnId(true); - } - - /** * 保存数据,并设置是否忽略 {@code null} 值。 * @@ -103,26 +93,15 @@ public interface MapperModel { } /** - * 保存数据并返回 entity 本身,并设置是否忽略 {@code null} 值。 + * 保存数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} + * 返回源对象回调,保存成功返回 {@code Optional.of(this)},保存失败返回 + * {@code Optional.empty()}。 * * @param ignoreNulls 是否忽略 {@code null} 值 - * @return entity 本身 + * @return {@link Optional} 链式调用 */ - default T saveAndReturnSelf(boolean ignoreNulls) { - baseMapper().insert((T) this, ignoreNulls); - return (T) this; - } - - - /** - * 保存数据并返回保存成功的 id,并设置是否忽略 {@code null} 值。 - * - * @param ignoreNulls 是否忽略 {@code null} 值 - * @return id 内容 - */ - default R saveAndReturnId(boolean ignoreNulls) { - baseMapper().insert((T) this, ignoreNulls); - return (R) pkValue(); + default Optional saveOpt(boolean ignoreNulls) { + return save(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); } /** @@ -135,6 +114,18 @@ public interface MapperModel { return saveOrUpdate(true); } + /** + * 保存或者更新数据,如果实体类主键没有值,则 保存 数据;如果实体类主键有值,则 + * 更新 数据(全部自动忽略 {@code null} 值),结果使用 {@link Optional} + * 返回源对象回调,保存或更新成功返回 {@code Optional.of(this)},保存或更新失败返回 + * {@code Optional.empty()}。 + * + * @return {@link Optional} 链式调用 + */ + default Optional saveOrUpdateOpt() { + return saveOrUpdateOpt(true); + } + /** * 保存或者更新数据,如果实体类主键没有值,则 保存 数据;如果实体类主键有值,则 * 更新 数据,并设置是否忽略 {@code null} 值。 @@ -146,6 +137,19 @@ public interface MapperModel { return SqlUtil.toBool(baseMapper().insertOrUpdate((T) this, ignoreNulls)); } + /** + * 保存或者更新数据,如果实体类主键没有值,则 保存 数据;如果实体类主键有值,则 + * 更新 数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} + * 返回源对象回调,保存或更新成功返回 {@code Optional.of(this)},保存或更新失败返回 + * {@code Optional.empty()}。 + * + * @param ignoreNulls 是否忽略 {@code null} 值 + * @return {@link Optional} 链式调用 + */ + default Optional saveOrUpdateOpt(boolean ignoreNulls) { + return saveOrUpdate(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); + } + /** * 根据实体类主键删除数据。 * @@ -155,6 +159,16 @@ public interface MapperModel { return SqlUtil.toBool(baseMapper().deleteById((Serializable) pkValue())); } + /** + * 根据实体类主键删除数据,结果使用 {@link Optional} 返回源对象回调,删除成功返回 + * {@code Optional.of(this)},删除失败返回 {@code Optional.empty()}。 + * + * @return {@link Optional} 链式调用 + */ + default Optional removeByIdOpt() { + return removeById() ? Optional.of((T) this) : Optional.empty(); + } + /** * 根据实体类主键更新数据(自动忽略 {@code null} 值)。 * @@ -164,6 +178,17 @@ public interface MapperModel { return updateById(true); } + /** + * 根据实体类主键更新数据(自动忽略 {@code null} 值),结果使用 {@link Optional} + * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 + * {@code Optional.empty()}。 + * + * @return {@link Optional} 链式调用 + */ + default Optional updateByIdOpt() { + return updateByIdOpt(true); + } + /** * 根据实体类主键更新数据,并设置是否忽略 {@code null} 值。 * @@ -174,6 +199,18 @@ public interface MapperModel { return SqlUtil.toBool(baseMapper().update((T) this, ignoreNulls)); } + /** + * 根据实体类主键更新数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} + * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 + * {@code Optional.empty()}。 + * + * @param ignoreNulls 是否忽略 {@code null} 值 + * @return {@link Optional} 链式调用 + */ + default Optional updateByIdOpt(boolean ignoreNulls) { + return updateById(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); + } + /** * 根据实体类主键获取一条数据。 * diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/Model.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/Model.java index d6d2bd11..9602f14d 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/Model.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/Model.java @@ -25,6 +25,7 @@ import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.util.SqlUtil; import java.io.Serializable; +import java.util.Optional; /** * Active Record 模型。 @@ -47,6 +48,16 @@ public abstract class Model> return SqlUtil.toBool(baseMapper().deleteByQuery(queryWrapper())); } + /** + * 根据实体类构建的条件删除数据,结果使用 {@link Optional} 返回源对象回调,删除成功返回 + * {@code Optional.of(this)},删除失败返回 {@code Optional.empty()}。 + * + * @return {@link Optional} 链式调用 + */ + public Optional removeOpt() { + return remove() ? Optional.of((T) this) : Optional.empty(); + } + /** * 根据实体类构建的条件更新数据(自动忽略 {@code null} 值)。 * @@ -56,6 +67,17 @@ public abstract class Model> return update(true); } + /** + * 根据实体类构建的条件更新数据(自动忽略 {@code null} 值),结果使用 {@link Optional} + * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 + * {@code Optional.empty()}。 + * + * @return {@link Optional} 链式调用 + */ + public Optional updateOpt() { + return updateOpt(true); + } + /** * 根据实体类构建的条件更新数据,并设置是否忽略 {@code null} 值。 * @@ -66,6 +88,18 @@ public abstract class Model> return SqlUtil.toBool(baseMapper().updateByQuery((T) this, ignoreNulls, queryWrapper())); } + /** + * 根据实体类构建的条件更新数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} + * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 + * {@code Optional.empty()}。 + * + * @param ignoreNulls 是否忽略 {@code null} 值 + * @return {@link Optional} 链式调用 + */ + public Optional updateOpt(boolean ignoreNulls) { + return update(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); + } + @Override public BaseMapper baseMapper() { return MapperModel.super.baseMapper(); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/FieldsQuery.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/FieldsQuery.java index 18494763..54454ab6 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/FieldsQuery.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/FieldsQuery.java @@ -51,7 +51,6 @@ public class FieldsQuery> extends FieldsBuilder { return this; } - protected Object pkValue() { // 懒加载,实际用到的时候才会生成 主键值 return ((Model) delegate).pkValue(); diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/java/com/mybatisflex/test/model/GoodOnSetListener.java b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/java/com/mybatisflex/test/model/GoodOnSetListener.java index 9585ebca..e440b691 100644 --- a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/java/com/mybatisflex/test/model/GoodOnSetListener.java +++ b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/java/com/mybatisflex/test/model/GoodOnSetListener.java @@ -27,7 +27,7 @@ public class GoodOnSetListener implements SetListener { @Override public Object onSet(Object entity, String property, Object value) { System.out.println("Good: " + property + " --- " + value); - return null; + return value; } } diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/resources/application.yml b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/resources/application.yml index be1c97b5..518df747 100644 --- a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/resources/application.yml +++ b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/resources/application.yml @@ -36,13 +36,13 @@ spring: # url: jdbc:mysql://localhost:3306/flex_test # username: root # password: 12345678 -mybatis-flex: - datasource: - ds1: - url: jdbc:mysql://127.0.0.1:3306/flex_test - username: root - password: 123456 - ds2: - url: jdbc:mysql://127.0.0.1:3306/flex_test - username: root - password: 123456 +#mybatis-flex: +# datasource: +# ds1: +# url: jdbc:mysql://127.0.0.1:3306/flex_test +# username: root +# password: 123456 +# ds2: +# url: jdbc:mysql://127.0.0.1:3306/flex_test +# username: root +# password: 123456 diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/ActiveRecordTest.java b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/ActiveRecordTest.java index 99eede8d..26ced894 100644 --- a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/ActiveRecordTest.java +++ b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/ActiveRecordTest.java @@ -57,6 +57,18 @@ class ActiveRecordTest { Assertions.assertTrue(saved); } + @Test + void testInsertCallback() { + Integer goodId = Good.create() + .setPrice(28.0) + .setName("摆渡人") + .saveOpt() + .orElseThrow(RuntimeException::new) + .getGoodId(); + + System.out.println(goodId); + } + @Test void testUpdate() { Good.create()