Common CRUD methods of mybatisplus
As we all know, mybatisplus provides powerful code generation capabilities. The definitions of commonly used CRUD methods (such as insert, update, delete, query, etc.) generated by it by default can help us save a lot of manual labor.
These commonly used CRUD methods are defined in it BaseMapper
. When we use it, inheriting this BaseMapper
class will have these capabilities by default.
If we need similar universal Sql in our business, how should we implement it?
Is similar Sql defined in each Mapper?
Obviously this is the stupidest method.
At this time we can use mybatisplus
this mature framework to implement the general Sql we want.
Extend common CRUD methods
Add a new general sql
For example, if there is a requirement that all tables or some tables in the project need to execute a similar query, such as `SelectByErp`, then it can be implemented like this. (This is the simplest SQL implementation. When used, more complex SQL can be implemented according to business needs: for example, a multi-tenant system automatically adds tenant id parameters, and a sub-database and sub-table system adds sub-database and sub-table field condition judgment)
-
Define a
SelectByErp
class, inheritAbstractMethod
the class, and implementinjectMappedStatement
the methods -
Define sql method names, sql templates, and implement sql splicing and assembly
/**
* 新增一个通用sql
*/
public class SelectByErp extends AbstractMethod {
// 需要查询的列名
private final String erpColumn = "erp";
// sql方法名
private final String method = "selectByErp";
// sql模板
private final String sqlTemplate = "SELECT %s FROM %s WHERE %s=#{%s} %s";
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
// 获取需要查询的字段名及属性名
TableFieldInfo erpFiled = getErpProperty(tableInfo);
// 拼接组装sql
SqlSource sqlSource = new RawSqlSource(configuration, String.format(sqlTemplate,
sqlSelectColumns(tableInfo, false),
tableInfo.getTableName(),
erpFiled.getColumn(), erpFiled.getProperty(),
tableInfo.getLogicDeleteSql(true, false)), Object.class);
return this.addSelectMappedStatementForTable(mapperClass, method, sqlSource, tableInfo);
}
/**
* 查询erp列信息
*/
private TableFieldInfo getErpProperty(TableInfo tableInfo) {
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
TableFieldInfo erpField = fieldList.stream().filter(filed -> filed.getColumn().equals(erpColumn)).findFirst().get();
return erpField;
}
3. Define a sql injector GyhSqlInjector
and add SelectByErp
objects
// 需注入到spring容器中
@Component
public class GyhSqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
// 增加 SelectByErp对象,程序启动后自动加载
methodList.add(new SelectByErp());
return methodList;
}
}
4. Define a basic Mapper GyhBaseMapper
and add selectByErp
methods
/**
* 自定义的通用Mapper
*/
public interface GyhBaseMapper<T> extends BaseMapper<T> {
List<T> selectByErp(String erp);
}
5. If all the tables in the application that need to use this SelectByErp
method are inherited GyhBaseMapper
, then these tables will all have selectByErp
this query method, and the SQL will be automatically generated for these tables after the program is started.
public interface XXXMapper extends GyhBaseMapper<XXXTable>
Add a mybatisplus already has sql
1. Mybatisplus commonly used CRUD methods are as shown in the picture above. These methods are automatically generated by default, but mybatisplus actually provides more methods, as shown below. As long as we add them at startup, they can be used.
2. For example, I want to use AlwaysUpdateSomeColumnById
a method that can only update the fields I need when updating, without updating all fields. The steps to add are as follows.
3. Define a sql injector, such as GyhSqlInjector
adding AlwaysUpdateSomeColumnById
objects
@Component
public class GyhSqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
// 添加 AlwaysUpdateSomeColumnById 对象
methodList.add(new AlwaysUpdateSomeColumnById());
return methodList;
}
}
4. Define a basic Mapper, such as GyhBaseMapper
adding alwaysUpdateSomeColumnById
methods
/**
* 自定义的通用Mapper
*/
public interface GyhBaseMapper<T> extends BaseMapper<T> {
int alwaysUpdateSomeColumnById(@Param(Constants.ENTITY) T entity);
}
5. GyhBaseMapper
Other inherited Mappers will automatically have alwaysUpdateSomeColumnById
methods
/**
* 自定义的通用Mapper
*/
public interface GyhBaseMapper<T> extends BaseMapper<T> {
int alwaysUpdateSomeColumnById(@Param(Constants.ENTITY) T entity);
}
6. GyhBaseMapper
Other inherited Mappers will automatically have alwaysUpdateSomeColumnById
methods
Edit a mybatisplus existing sql
1. If you want to edit an existing sql in mybatisplus, such as a sub-database and sub-table system, updateById
when performing the operation, although the primary key ID has been determined, the target table is uncertain. At this time, the sql may be executed on multiple tables, resulting in a waste of resources. , and the sub-database and sub-table fields cannot be modified. The default ones updateById
cannot be used and need to be modified. The following takes shardingsphere
sub-database and sub-table as an example.
2. Define a UpdateByIdWithSharding
class and inherit UpdateById
the class
public class UpdateByIdWithSharding extends UpdateById {
private String columnDot = "`";
private YamlShardingRuleConfiguration yamlShardingRuleConfiguration;
// 注入shardingsphere的分库分表配置信息
public UpdateByIdWithSharding(YamlShardingRuleConfiguration yamlShardingRuleConfiguration) {
this.yamlShardingRuleConfiguration = yamlShardingRuleConfiguration;
}
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String tableName = tableInfo.getTableName();
// shardingsphere 分库分表配置信息
Map<String, YamlTableRuleConfiguration> tables = yamlShardingRuleConfiguration.getTables();
// 判断当前表是否设置了分表字段
if (tables.containsKey(tableName)) {
YamlTableRuleConfiguration tableRuleConfiguration = tables.get(tableName);
// 获取分表字段
String shardingColumn = tableRuleConfiguration.getTableStrategy().getStandard().getShardingColumn();
// 构建sql
boolean logicDelete = tableInfo.isLogicDelete();
SqlMethod sqlMethod = SqlMethod.UPDATE_BY_ID;
// 增加分表字段判断
String shardingAdditional = getShardingColumnWhere(tableInfo, shardingColumn);
// 是否判断逻辑删除字段
final String additional = optlockVersion() + tableInfo.getLogicDeleteSql(true, false);
shardingAdditional = shardingAdditional + additional;
String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(),
getSqlSet(logicDelete, tableInfo, shardingColumn),
tableInfo.getKeyColumn(), ENTITY_DOT + tableInfo.getKeyProperty(),
shardingAdditional);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
} else {
return super.injectMappedStatement(mapperClass, modelClass, tableInfo);
}
}
/**
* where条件增加分表字段
*/
private String getShardingColumnWhere(TableInfo tableInfo, String shardingColumn) {
StringBuilder shardingWhere = new StringBuilder();
shardingWhere.append(" AND ").append(shardingColumn).append("=#{");
shardingWhere.append(ENTITY_DOT);
TableFieldInfo fieldInfo = tableInfo.getFieldList().stream()
.filter(f -> f.getColumn().replaceAll(columnDot, StringUtils.EMPTY).equals(shardingColumn))
.findFirst().get();
shardingWhere.append(fieldInfo.getEl());
shardingWhere.append("}");
return shardingWhere.toString();
}
/**
* set模块去掉分表字段
*/
public String getSqlSet(boolean ignoreLogicDelFiled, TableInfo tableInfo, String shardingColumn) {
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
// 去掉分表字段的set设置,即不修改分表字段
String rmShardingColumnSet = fieldList.stream()
.filter(i -> ignoreLogicDelFiled ? !(tableInfo.isLogicDelete() && i.isLogicDelete()) : true)
.filter(i -> !i.getColumn().equals(shardingColumn))
.map(i -> i.getSqlSet(ENTITY_DOT))
.filter(Objects::nonNull).collect(joining(NEWLINE));
return rmShardingColumnSet;
}
}
3. Define a sql injector GyhSqlInjector
and add UpdateByIdWithSharding
objects
// 需注入到spring容器中
@Component
public class GyhSqlInjector extends DefaultSqlInjector {
/**
* shardingsphere 配置信息
*/
@Autowired
private YamlShardingRuleConfiguration yamlShardingRuleConfiguration;
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
// 添加 UpdateByIdWithSharding 对象,并注入分库分表信息
methodList.add(new UpdateByIdWithSharding(yamlShardingRuleConfiguration));
return methodList;
}
}
4. Define a basic Mapper GyhBaseMapper
and add new selectById
methods
/**
* 自定义的通用Mapper
*/
public interface GyhBaseMapper<T> extends BaseMapper<T> {
int updateById(@Param(Constants.ENTITY) T entity);
}
5. All tables participating in table sharding are inherited when defining Mapper GyhBaseMapper
. Then when using its updateById
method, the judgment of sharding database and table will be automatically added, accurately hitting the target table, and reducing the waste of resources in other sharding queries.
The above are mybatisplus
some simple modifications, I hope it can provide you with a little help~
Alibaba Cloud suffered a serious failure and all products were affected (restored). Tumblr cooled down the Russian operating system Aurora OS 5.0. New UI unveiled Delphi 12 & C++ Builder 12, RAD Studio 12. Many Internet companies urgently recruit Hongmeng programmers. UNIX time is about to enter the 1.7 billion era (already entered). Meituan recruits troops and plans to develop the Hongmeng system App. Amazon develops a Linux-based operating system to get rid of Android's dependence on .NET 8 on Linux. The independent size is reduced by 50%. FFmpeg 6.1 "Heaviside" is releasedAuthor: JD Technology Guo Yanhong
Source: JD Cloud Developer Community Please indicate the source when reprinting