第十三章:mybatis-plus 自定义查询方法

在mybatis-plus内部实现了一系列的操作数据库的SQL语句方法,但是某些特殊情况这些方法不能满足需求时,如何自定义通用方法呢?首先我们研究一下mybatis-plus内部如何实现的?

主要是通过下类定义的

public class DefaultSqlInjector extends AbstractSqlInjector {

public DefaultSqlInjector() {

}

public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {

Builder<AbstractMethod> builder = Stream.builder().add(new Insert()).add(new Delete()).add(new DeleteByMap()).add(new Update()).add(new SelectByMap()).add(new SelectCount()).add(new SelectMaps()).add(new SelectMapsPage()).add(new SelectObjs()).add(new SelectList()).add(new SelectPage());

if (tableInfo.havePK()) {

builder.add(new DeleteById()).add(new DeleteBatchByIds()).add(new UpdateById()).add(new SelectById()).add(new SelectBatchByIds());

} else {

this.logger.warn(String.format("%s ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.", tableInfo.getEntityType()));

}

return (List)builder.build().collect(Collectors.toList());

}

}

而这些方法实现是通过继承类来实现AbstractMethod,比如Insert类

最关键的部分通过injectMappedStatement方法生成操作数据的SQL,还有里面最关键的sqlMethod

public class Insert extends AbstractMethod {

public Insert() {

super(SqlMethod.INSERT_ONE.getMethod());

}

public Insert(String name) {

super(name);

}

public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {

KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE;

SqlMethod sqlMethod = SqlMethod.INSERT_ONE;

String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumnMaybeIf((String)null), "(", ")", (String)null, ",");

String valuesScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlPropertyMaybeIf((String)null), "(", ")", (String)null, ",");

String keyProperty = null;

String keyColumn = null;

if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {

if (tableInfo.getIdType() == IdType.AUTO) {

keyGenerator = Jdbc3KeyGenerator.INSTANCE;

keyProperty = tableInfo.getKeyProperty();

keyColumn = tableInfo.getKeyColumn();

} else if (null != tableInfo.getKeySequence()) {

keyGenerator = TableInfoHelper.genKeyGenerator(this.methodName, tableInfo, this.builderAssistant);

keyProperty = tableInfo.getKeyProperty();

keyColumn = tableInfo.getKeyColumn();

}

}

String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);

SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);

return this.addInsertMappedStatement(mapperClass, modelClass, this.getMethod(sqlMethod), sqlSource, (KeyGenerator)keyGenerator, keyProperty, keyColumn);

}

}

另外需要实际可以使用,mybatis-plus是在BaseMapper接口中定义了Insert方法:

public interface BaseMapper<T> extends Mapper<T> {

int insert(T entity);

int deleteById(Serializable id);

int deleteById(T entity);

int deleteByMap(@Param("cm") Map<String, Object> columnMap);

下面我们看一下如何实现自定义method

1.准备CustomMethod类

public class CustomMethod extends AbstractMethod {

private String method="customMethod";

@Override

public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {

String sql="select id,name,age,version from "+tableInfo.getTableName()+" where "+tableInfo.getKeyColumn()+ "=#{" + tableInfo.getKeyProperty() + "}";

SqlSource sqlSource= languageDriver.createSqlSource(configuration,sql,modelClass);

return addSelectMappedStatementForTable(mapperClass,method,sqlSource,tableInfo);

}

}

2.准备SqlInject类

public class CustomSqlInjector extends DefaultSqlInjector {

@Override

public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {

List<AbstractMethod> methodList= super.getMethodList(mapperClass, tableInfo);

methodList.add(new CustomMethod());

return methodList;

}

}

3.准备CustomMapper类继承BaseMapper类,在里面添加自定义方法

public interface CustomBaseMapper<T> extends BaseMapper<T> {

T customMethod(Serializable id);

}

4.在Configuration类中生成CustomSqlInjector 的Bean

@Configuration

public class MybatisPlusConfig {

@Bean

public CustomSqlInjector customSqlInjector(){

return new CustomSqlInjector();

}

5.让UserMapper继承CustomMapper类

public interface UserMapper extends CustomBaseMapper<User> {

@Select("select * from user ${ew.customSqlSegment}")

List<User> selectAllUser(@Param(Constants.WRAPPER)Wrapper<User> wrapper);

List<User> selectUsers(@Param(Constants.WRAPPER)Wrapper<User> wrapper);

IPage<User> selectUserPage(Page<User> page,@Param(Constants.WRAPPER)Wrapper<User> wrapper);

}

6.准备测试用例

@Test

public void testCustomMethod(){

User user= userMapper.customMethod(413l);

System.out.println(user);

}

7.运行日志

2022-10-11 18:48:33.049 DEBUG 26000 --- [ main] c.m.s.mapper.UserMapper.customMethod : ==> Preparing: SELECT id, name, age, version FROM user WHERE id = ? AND user.FAB = 'FAB1'

2022-10-11 18:48:33.078 DEBUG 26000 --- [ main] c.m.s.mapper.UserMapper.customMethod : ==> Parameters: 413(Long)

Consume Time:10 ms 2022-10-11 18:48:33

Execute SQL:SELECT id, name, age, version FROM user WHERE id = 413 AND user.FAB = 'FAB1'

2022-10-11 18:48:33.104 DEBUG 26000 --- [ main] c.m.s.mapper.UserMapper.customMethod : <== Total: 1

另外mybatis-plus还提供一些选装方法,具体如下,在使用时需要按照上面的方法进行。

public class AlwaysUpdateSomeColumnById extends AbstractMethod

public class InsertBatchSomeColumn extends AbstractMethod

public class LogicDeleteBatchByIds extends DeleteBatchByIds

public class LogicDeleteByIdWithFill extends AbstractMethod

public class Upsert extends AbstractMethod

以上方法类具体的功能可以通过IDEA查看代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值