!301 feat:Active Record 模式添加回调方法,用于继续使用实体类。

Merge pull request !301 from 王帅/main
This commit is contained in:
Michael Yang 2023-08-23 01:48:46 +00:00 committed by Gitee
commit c51504ed03
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
13 changed files with 554 additions and 179 deletions

View File

@ -201,3 +201,20 @@ User.create()
``` ```
> 获取更多关于 `Fields Query` 的信息,请点击 [这里](./relations-query.md#方案-2field-query) > 获取更多关于 `Fields Query` 的信息,请点击 [这里](./relations-query.md#方案-2field-query)
## 回调方法 <Badge type="tip" text="v1.5.9" />
有些情况下,我们在操作完数据库后,还需要继续使用实体类的内容,例如:获取插入数据后返回的主键。此时这些返回值为 `boolean` 的方法就不满足我们的需求了,
应该使用 `xxxOpt` 方法,在操作数据库执行成功之后返回 `Optional.of(this)`,执行失败返回 `Optional.empty()`。这样就可以进行链式的调用了。
```java
// 插入成功之后返回主键信息
Account.create()
.setUserName("张三")
.setAge(18)
.setBirthday(new Date())
.saveCallback()
.orElseThrow(RuntimeException::new) // 保存失败抛出异常
.getId();
```

View File

@ -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;
}
} }

View File

@ -24,8 +24,11 @@ import java.io.Serializable;
/** /**
* 表字段的单独设置 * 表字段的单独设置
*/ */
@SuppressWarnings({"rawtypes", "UnusedReturnValue", "unused"})
public class ColumnConfig implements Serializable { public class ColumnConfig implements Serializable {
private static final long serialVersionUID = -1511605303951623381L;
/** /**
* 字段名称 * 字段名称
*/ */
@ -56,6 +59,11 @@ public class ColumnConfig implements Serializable {
*/ */
private Boolean version; private Boolean version;
/**
* 是否是租户 ID
*/
private Boolean tenantId;
/** /**
* 配置的 jdbcType * 配置的 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; private Boolean keyBefore;
/** public static ColumnConfig create() {
* 是否是租户 ID return new ColumnConfig();
*/
private Boolean tenantId;
public String getColumnName() {
return columnName;
} }
public void setColumnName(String columnName) { public String getColumnName() {
return this.columnName;
}
public ColumnConfig setColumnName(String columnName) {
this.columnName = columnName; this.columnName = columnName;
return this;
} }
public String getOnInsertValue() { public String getOnInsertValue() {
return onInsertValue; return this.onInsertValue;
} }
public void setOnInsertValue(String onInsertValue) { public ColumnConfig setOnInsertValue(String onInsertValue) {
this.onInsertValue = onInsertValue; this.onInsertValue = onInsertValue;
return this;
} }
public String getOnUpdateValue() { public String getOnUpdateValue() {
return onUpdateValue; return this.onUpdateValue;
} }
public void setOnUpdateValue(String onUpdateValue) { public ColumnConfig setOnUpdateValue(String onUpdateValue) {
this.onUpdateValue = onUpdateValue; this.onUpdateValue = onUpdateValue;
return this;
} }
public Boolean getLarge() { public Boolean getLarge() {
return isLarge; return this.isLarge;
} }
public void setLarge(Boolean large) { public ColumnConfig setLarge(Boolean large) {
isLarge = large; this.isLarge = large;
return this;
} }
public Boolean getLogicDelete() { public Boolean getLogicDelete() {
return isLogicDelete; return this.isLogicDelete;
} }
public void setLogicDelete(Boolean logicDelete) { public ColumnConfig setLogicDelete(Boolean logicDelete) {
isLogicDelete = logicDelete; this.isLogicDelete = logicDelete;
return this;
} }
public Boolean getVersion() { public Boolean getVersion() {
return version; return this.version;
} }
public void setVersion(Boolean version) { public ColumnConfig setVersion(Boolean version) {
this.version = version; this.version = version;
} return this;
public JdbcType getJdbcType() {
return jdbcType;
}
public void setJdbcType(JdbcType jdbcType) {
this.jdbcType = jdbcType;
}
public Class<? extends TypeHandler> getTypeHandler() {
return typeHandler;
}
public void setTypeHandler(Class<? extends TypeHandler> 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;
} }
public Boolean getTenantId() { public Boolean getTenantId() {
return tenantId; return this.tenantId;
} }
public void setTenantId(Boolean tenantId) { public ColumnConfig setTenantId(Boolean tenantId) {
this.tenantId = 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() { public String getPropertyType() {
return propertyType; return this.propertyType;
} }
/** public ColumnConfig setPropertyType(String propertyType) {
* 原始类型直接写类型名称int/long/float/double/boolean对象类型请写对应类的全限定名java.lang.String
*/
public void setPropertyType(String propertyType) {
this.propertyType = propertyType; this.propertyType = propertyType;
return this;
} }
public String getPropertyDefaultValue() { public String getPropertyDefaultValue() {
return propertyDefaultValue; return this.propertyDefaultValue;
} }
public void setPropertyDefaultValue(String propertyDefaultValue) { public ColumnConfig setPropertyDefaultValue(String propertyDefaultValue) {
this.propertyDefaultValue = propertyDefaultValue; this.propertyDefaultValue = propertyDefaultValue;
return this;
} }
public Class<? extends TypeHandler> getTypeHandler() {
return this.typeHandler;
}
public ColumnConfig setTypeHandler(Class<? extends TypeHandler> 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<? extends TypeHandler> 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;
}
}
} }

View File

@ -87,6 +87,7 @@ public class StrategyConfig {
public Set<String> getIgnoreColumns() { public Set<String> getIgnoreColumns() {
return ignoreColumns; return ignoreColumns;
} }
/** /**
* 设置需要忽略的列 全局配置 * 设置需要忽略的列 全局配置
*/ */
@ -121,7 +122,8 @@ public class StrategyConfig {
* 获取表配置 * 获取表配置
*/ */
public TableConfig getTableConfig(String tableName) { 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); setTableConfig(tableConfig);
} }
tableConfig.addColumnConfig(columnConfig); tableConfig.setColumnConfig(columnConfig);
return this; return this;
} }

View File

@ -25,18 +25,21 @@ import java.util.Map;
/** /**
* 表的单独设置 * 表的单独设置
*/ */
@SuppressWarnings({"unused", "UnusedReturnValue"})
public class TableConfig { public class TableConfig {
/** public static final String ALL_TABLES = "*";
* 表名
*/
private String tableName;
/** /**
* 数据库的 schema模式 * 数据库的 schema模式
*/ */
private String schema; private String schema;
/**
* 表名
*/
private String tableName = ALL_TABLES;
/** /**
* 默认为 驼峰属性 转换为 下划线字段 * 默认为 驼峰属性 转换为 下划线字段
*/ */
@ -57,89 +60,160 @@ public class TableConfig {
*/ */
private Class<? extends SetListener> setListenerClass; private Class<? extends SetListener> setListenerClass;
/**
* 对应列的配置
*/
private Map<String, ColumnConfig> columnConfigMap;
/** /**
* 是否开启 Mapper 生成 * 是否开启 Mapper 生成
*/ */
private Boolean mapperGenerateEnable = Boolean.TRUE; private Boolean mapperGenerateEnable = Boolean.TRUE;
public String getTableName() { /**
return tableName; * 对应列的配置
} */
private Map<String, ColumnConfig> columnConfigMap;
public void setTableName(String tableName) { public static TableConfig create() {
this.tableName = tableName; return new TableConfig();
} }
public String getSchema() { public String getSchema() {
return schema; return this.schema;
} }
public void setSchema(String schema) { public TableConfig setSchema(String schema) {
this.schema = 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() { public Boolean getCamelToUnderline() {
return camelToUnderline; return this.camelToUnderline;
} }
public void setCamelToUnderline(Boolean camelToUnderline) { public TableConfig setCamelToUnderline(Boolean camelToUnderline) {
this.camelToUnderline = camelToUnderline; this.camelToUnderline = camelToUnderline;
return this;
} }
public Class<? extends InsertListener> getInsertListenerClass() { public Class<? extends InsertListener> getInsertListenerClass() {
return insertListenerClass; return this.insertListenerClass;
} }
public void setInsertListenerClass(Class<? extends InsertListener> insertListenerClass) { public TableConfig setInsertListenerClass(Class<? extends InsertListener> insertListenerClass) {
this.insertListenerClass = insertListenerClass; this.insertListenerClass = insertListenerClass;
return this;
} }
public Class<? extends UpdateListener> getUpdateListenerClass() { public Class<? extends UpdateListener> getUpdateListenerClass() {
return updateListenerClass; return this.updateListenerClass;
} }
public void setUpdateListenerClass(Class<? extends UpdateListener> updateListenerClass) { public TableConfig setUpdateListenerClass(Class<? extends UpdateListener> updateListenerClass) {
this.updateListenerClass = updateListenerClass; this.updateListenerClass = updateListenerClass;
return this;
} }
public Class<? extends SetListener> getSetListenerClass() { public Class<? extends SetListener> getSetListenerClass() {
return setListenerClass; return this.setListenerClass;
} }
public void setSetListenerClass(Class<? extends SetListener> setListenerClass) { public TableConfig setSetListenerClass(Class<? extends SetListener> setListenerClass) {
this.setListenerClass = setListenerClass; this.setListenerClass = setListenerClass;
} return this;
public Map<String, ColumnConfig> getColumnConfigMap() {
return columnConfigMap;
}
public void setColumnConfigMap(Map<String, ColumnConfig> columnConfigMap) {
this.columnConfigMap = columnConfigMap;
} }
public Boolean getMapperGenerateEnable() { public Boolean getMapperGenerateEnable() {
return mapperGenerateEnable; return this.mapperGenerateEnable;
} }
public void setMapperGenerateEnable(Boolean mapperGenerateEnable) { public TableConfig setMapperGenerateEnable(Boolean mapperGenerateEnable) {
this.mapperGenerateEnable = mapperGenerateEnable; this.mapperGenerateEnable = mapperGenerateEnable;
return this;
} }
public void addColumnConfig(ColumnConfig columnConfig) { public Map<String, ColumnConfig> getColumnConfigMap() {
if (columnConfigMap == null) { return this.columnConfigMap;
columnConfigMap = new HashMap<>(); }
}
columnConfigMap.put(columnConfig.getColumnName(), columnConfig); public TableConfig setColumnConfigMap(Map<String, ColumnConfig> columnConfigMap) {
this.columnConfigMap = columnConfigMap;
return this;
}
public TableConfig setColumnConfig(ColumnConfig columnConfig) {
if (this.columnConfigMap == null) {
this.columnConfigMap = new HashMap<>();
}
this.columnConfigMap.put(columnConfig.getColumnName(), columnConfig);
return this;
}
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<? extends InsertListener> insertListenerClass) {
this.tableConfig.setInsertListenerClass(insertListenerClass);
return this;
}
public Builder updateListenerClass(Class<? extends UpdateListener> updateListenerClass) {
this.tableConfig.setUpdateListenerClass(updateListenerClass);
return this;
}
public Builder setListenerClass(Class<? extends SetListener> 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;
} }
public ColumnConfig getColumnConfig(String columnName) {
return columnConfigMap == null ? null : columnConfigMap.get(columnName);
} }
} }

View File

@ -295,8 +295,8 @@ public class Column {
} }
//@ColumnMask 注解 //@ColumnMask 注解
if (columnConfig.getMask() != null) { if (columnConfig.getMaskType() != null) {
annotations.append("@ColumnMask(\"").append(columnConfig.getMask()).append("\")"); annotations.append("@ColumnMask(\"").append(columnConfig.getMaskType()).append("\")");
} }
return annotations.toString(); return annotations.toString();
@ -324,7 +324,7 @@ public class Column {
if (columnConfig.getPropertyType() != null) { if (columnConfig.getPropertyType() != null) {
addImportClass(importClasses, columnConfig.getPropertyType()); addImportClass(importClasses, columnConfig.getPropertyType());
} }
if (columnConfig.getMask() != null) { if (columnConfig.getMaskType() != null) {
addImportClass(importClasses, ColumnMask.class.getName()); addImportClass(importClasses, ColumnMask.class.getName());
} }

View File

@ -23,6 +23,7 @@ import com.mybatisflex.codegen.config.TableConfig;
import com.mybatisflex.codegen.config.TableDefConfig; import com.mybatisflex.codegen.config.TableDefConfig;
import com.mybatisflex.codegen.constant.TemplateConst; import com.mybatisflex.codegen.constant.TemplateConst;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import org.junit.Test;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
@ -189,7 +190,7 @@ public class GeneratorTest {
TableConfig tableConfig = new TableConfig(); TableConfig tableConfig = new TableConfig();
tableConfig.setTableName("sys_user"); tableConfig.setTableName("sys_user");
tableConfig.addColumnConfig(columnConfig); tableConfig.setColumnConfig(columnConfig);
ColumnConfig logicDelete = new ColumnConfig(); ColumnConfig logicDelete = new ColumnConfig();
logicDelete.setColumnName("del_flag"); logicDelete.setColumnName("del_flag");
@ -276,4 +277,72 @@ public class GeneratorTest {
generator.generate(); 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<String> 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();
}
} }

View File

@ -71,27 +71,17 @@ public interface MapperModel<T> {
return save(true); 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() { default Optional<T> saveOpt() {
return saveAndReturnSelf(true); return saveOpt(true);
} }
/**
* 保存数据并返回保存成功的 id并设置是否忽略 {@code null}
*
* @return id
*/
default <R> R saveAndReturnId() {
return saveAndReturnId(true);
}
/** /**
* 保存数据并设置是否忽略 {@code null} * 保存数据并设置是否忽略 {@code null}
* *
@ -103,26 +93,15 @@ public interface MapperModel<T> {
} }
/** /**
* 保存数据并返回 entity 本身并设置是否忽略 {@code null} * 保存数据并设置是否忽略 {@code null} 结果使用 {@link Optional}
* 返回源对象回调保存成功返回 {@code Optional.of(this)}保存失败返回
* {@code Optional.empty()}
* *
* @param ignoreNulls 是否忽略 {@code null} * @param ignoreNulls 是否忽略 {@code null}
* @return entity 本身 * @return {@link Optional} 链式调用
*/ */
default T saveAndReturnSelf(boolean ignoreNulls) { default Optional<T> saveOpt(boolean ignoreNulls) {
baseMapper().insert((T) this, ignoreNulls); return save(ignoreNulls) ? Optional.of((T) this) : Optional.empty();
return (T) this;
}
/**
* 保存数据并返回保存成功的 id并设置是否忽略 {@code null}
*
* @param ignoreNulls 是否忽略 {@code null}
* @return id 内容
*/
default <R> R saveAndReturnId(boolean ignoreNulls) {
baseMapper().insert((T) this, ignoreNulls);
return (R) pkValue();
} }
/** /**
@ -135,6 +114,18 @@ public interface MapperModel<T> {
return saveOrUpdate(true); return saveOrUpdate(true);
} }
/**
* 保存或者更新数据如果实体类主键没有值 <b>保存</b> 数据如果实体类主键有值
* <b>更新</b> 数据全部自动忽略 {@code null} 结果使用 {@link Optional}
* 返回源对象回调保存或更新成功返回 {@code Optional.of(this)}保存或更新失败返回
* {@code Optional.empty()}
*
* @return {@link Optional} 链式调用
*/
default Optional<T> saveOrUpdateOpt() {
return saveOrUpdateOpt(true);
}
/** /**
* 保存或者更新数据如果实体类主键没有值 <b>保存</b> 数据如果实体类主键有值 * 保存或者更新数据如果实体类主键没有值 <b>保存</b> 数据如果实体类主键有值
* <b>更新</b> 数据并设置是否忽略 {@code null} * <b>更新</b> 数据并设置是否忽略 {@code null}
@ -146,6 +137,19 @@ public interface MapperModel<T> {
return SqlUtil.toBool(baseMapper().insertOrUpdate((T) this, ignoreNulls)); return SqlUtil.toBool(baseMapper().insertOrUpdate((T) this, ignoreNulls));
} }
/**
* 保存或者更新数据如果实体类主键没有值 <b>保存</b> 数据如果实体类主键有值
* <b>更新</b> 数据并设置是否忽略 {@code null} 结果使用 {@link Optional}
* 返回源对象回调保存或更新成功返回 {@code Optional.of(this)}保存或更新失败返回
* {@code Optional.empty()}
*
* @param ignoreNulls 是否忽略 {@code null}
* @return {@link Optional} 链式调用
*/
default Optional<T> saveOrUpdateOpt(boolean ignoreNulls) {
return saveOrUpdate(ignoreNulls) ? Optional.of((T) this) : Optional.empty();
}
/** /**
* 根据实体类主键删除数据 * 根据实体类主键删除数据
* *
@ -155,6 +159,16 @@ public interface MapperModel<T> {
return SqlUtil.toBool(baseMapper().deleteById((Serializable) pkValue())); return SqlUtil.toBool(baseMapper().deleteById((Serializable) pkValue()));
} }
/**
* 根据实体类主键删除数据结果使用 {@link Optional} 返回源对象回调删除成功返回
* {@code Optional.of(this)}删除失败返回 {@code Optional.empty()}
*
* @return {@link Optional} 链式调用
*/
default Optional<T> removeByIdOpt() {
return removeById() ? Optional.of((T) this) : Optional.empty();
}
/** /**
* 根据实体类主键更新数据自动忽略 {@code null} * 根据实体类主键更新数据自动忽略 {@code null}
* *
@ -164,6 +178,17 @@ public interface MapperModel<T> {
return updateById(true); return updateById(true);
} }
/**
* 根据实体类主键更新数据自动忽略 {@code null} 结果使用 {@link Optional}
* 返回源对象回调更新成功返回 {@code Optional.of(this)}更新失败返回
* {@code Optional.empty()}
*
* @return {@link Optional} 链式调用
*/
default Optional<T> updateByIdOpt() {
return updateByIdOpt(true);
}
/** /**
* 根据实体类主键更新数据并设置是否忽略 {@code null} * 根据实体类主键更新数据并设置是否忽略 {@code null}
* *
@ -174,6 +199,18 @@ public interface MapperModel<T> {
return SqlUtil.toBool(baseMapper().update((T) this, ignoreNulls)); 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<T> updateByIdOpt(boolean ignoreNulls) {
return updateById(ignoreNulls) ? Optional.of((T) this) : Optional.empty();
}
/** /**
* 根据实体类主键获取一条数据 * 根据实体类主键获取一条数据
* *

View File

@ -25,6 +25,7 @@ import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.util.SqlUtil; import com.mybatisflex.core.util.SqlUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.Optional;
/** /**
* Active Record 模型 * Active Record 模型
@ -47,6 +48,16 @@ public abstract class Model<T extends Model<T>>
return SqlUtil.toBool(baseMapper().deleteByQuery(queryWrapper())); return SqlUtil.toBool(baseMapper().deleteByQuery(queryWrapper()));
} }
/**
* 根据实体类构建的条件删除数据结果使用 {@link Optional} 返回源对象回调删除成功返回
* {@code Optional.of(this)}删除失败返回 {@code Optional.empty()}
*
* @return {@link Optional} 链式调用
*/
public Optional<T> removeOpt() {
return remove() ? Optional.of((T) this) : Optional.empty();
}
/** /**
* 根据实体类构建的条件更新数据自动忽略 {@code null} * 根据实体类构建的条件更新数据自动忽略 {@code null}
* *
@ -56,6 +67,17 @@ public abstract class Model<T extends Model<T>>
return update(true); return update(true);
} }
/**
* 根据实体类构建的条件更新数据自动忽略 {@code null} 结果使用 {@link Optional}
* 返回源对象回调更新成功返回 {@code Optional.of(this)}更新失败返回
* {@code Optional.empty()}
*
* @return {@link Optional} 链式调用
*/
public Optional<T> updateOpt() {
return updateOpt(true);
}
/** /**
* 根据实体类构建的条件更新数据并设置是否忽略 {@code null} * 根据实体类构建的条件更新数据并设置是否忽略 {@code null}
* *
@ -66,6 +88,18 @@ public abstract class Model<T extends Model<T>>
return SqlUtil.toBool(baseMapper().updateByQuery((T) this, ignoreNulls, queryWrapper())); 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<T> updateOpt(boolean ignoreNulls) {
return update(ignoreNulls) ? Optional.of((T) this) : Optional.empty();
}
@Override @Override
public BaseMapper<T> baseMapper() { public BaseMapper<T> baseMapper() {
return MapperModel.super.baseMapper(); return MapperModel.super.baseMapper();

View File

@ -51,7 +51,6 @@ public class FieldsQuery<T extends Model<T>> extends FieldsBuilder<T> {
return this; return this;
} }
protected Object pkValue() { protected Object pkValue() {
// 懒加载实际用到的时候才会生成 主键值 // 懒加载实际用到的时候才会生成 主键值
return ((Model<T>) delegate).pkValue(); return ((Model<T>) delegate).pkValue();

View File

@ -27,7 +27,7 @@ public class GoodOnSetListener implements SetListener {
@Override @Override
public Object onSet(Object entity, String property, Object value) { public Object onSet(Object entity, String property, Object value) {
System.out.println("Good: " + property + " --- " + value); System.out.println("Good: " + property + " --- " + value);
return null; return value;
} }
} }

View File

@ -36,13 +36,13 @@ spring:
# url: jdbc:mysql://localhost:3306/flex_test # url: jdbc:mysql://localhost:3306/flex_test
# username: root # username: root
# password: 12345678 # password: 12345678
mybatis-flex: #mybatis-flex:
datasource: # datasource:
ds1: # ds1:
url: jdbc:mysql://127.0.0.1:3306/flex_test # url: jdbc:mysql://127.0.0.1:3306/flex_test
username: root # username: root
password: 123456 # password: 123456
ds2: # ds2:
url: jdbc:mysql://127.0.0.1:3306/flex_test # url: jdbc:mysql://127.0.0.1:3306/flex_test
username: root # username: root
password: 123456 # password: 123456

View File

@ -57,6 +57,18 @@ class ActiveRecordTest {
Assertions.assertTrue(saved); Assertions.assertTrue(saved);
} }
@Test
void testInsertCallback() {
Integer goodId = Good.create()
.setPrice(28.0)
.setName("摆渡人")
.saveOpt()
.orElseThrow(RuntimeException::new)
.getGoodId();
System.out.println(goodId);
}
@Test @Test
void testUpdate() { void testUpdate() {
Good.create() Good.create()