1 为什么需要做注入
MybatisPlus的方法是有限的,因为都是继承于 BaseMapper
父接口,这个父接口中的方法,虽然方法丰富,但有时可能无法满足我们更加多样的需求。
因此,需要使用SQL注入器来自定义全局方法,将其注入到全局中,这样所有的 Mapper 类都能调用到该方法。
以需要创建的方法为 selectAll()
为例进行说明。
2 创建注入方法类
注入方法类,需要继承自 AbstractMethod
抽象类,并实现该类中的抽象方法 injectMappedStatement()
。
在该抽象方法中:
- 我们可以自定义需要用到的SQL语句;
- 自定义调用的方法名;
- 构建
SqlSource
,将SQL语句传递到数据库中; - 构建查询方法,此处用到了查询,所以使用的是
addSelectMappedStatementForTable()
方法 (可以根据我们的需要,构建增、删、改、查各种类型的方法)。
以上步骤是固定的,其它方法的添加可以完全照搬。
代码语言:java复制import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
public class MyMethods extends AbstractMethod{
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
//定义SQL语句
String sql = "select * from " tableInfo.getTableName();
//方法名
String methodName = "selectAll";
//构建SqlSource,将SQL语句传递到数据库中
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
//构建查询方法
return this.addSelectMappedStatementForTable(mapperClass, methodName, sqlSource, tableInfo);
}
}
3 创建SQL注入器
3.1 继承AbstractSqlInjector
创建自定义注入器并继承抽象类 AbstractSqlInjector
,实现抽象方法 getMethodList()
,在该方法中,将上一步创建的自定义方法添加到MybatisPlus 中。
所有用到的方法都需要在这里重新添加,未在此添加的方法,都无法使用。
代码语言:java复制import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class MySQLInject extends AbstractSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methods = new ArrayList<>();
methods.add(new MyMethods());
return methods;
}
}
3.2 继承DefaultSqlInjector
创建自定义注入器并继承普通类 DefaultSqlInjector
,重写方法 getMethodList()
,在该方法中,通过super.getMethodList()
继承父类中所有方法,并将上一步创建的自定义方法添加到MybatisPlus 中。
这样,我们就能使用新建的方法及父类中的所有方法。
代码语言:java复制import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class MySQLInject extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methods = super.getMethodList(mapperClass, tableInfo);
methods.add(new MyMethods());
return methods;
}
}
4 在mapper接口中创建新方法
新方法的名字需要与第2步中的定义的方法名相同。
因为是查询所有记录,返回结果使用了 List 进行存储。
5 测试
因为我们注入的方法是在 mapper 中定义,所以这种方法只能在 mapper 模式下调用,ActiveRecord 模式不可用。
测试类中实例化了一个 UserMapper 接口,然后调用该接口的 selectAll()
方法。
在控制台输出的SQL语句如下:
==> Preparing: select * from user
==> Parameters:
<== Columns: id, username, gendar, remark, version, isDeleted
<== Row: 7, 韩梅梅, 女, 大堂经理, 0, 1
<== Row: 8, 李磊, 男, 美术老师, 0, 0
<== Row: 9, 李磊, 男, 英语老师, 0, 0
<== Row: 10, 张三, 女, 体育老师, 0, 0
<== Row: 11, 刘能, 男, 演讲老师, 0, 0
<== Row: 12, 赵敏, 女, 英语老师, 1, 0
<== Row: 21, 李世民, 男, 唐宗宋祖, 0, 0
<== Row: 22, 李世民, 男, 1唐宗宋祖, 1, 0
<== Row: 23, null, null, null, 0, 0
<== Total: 9
该方法可以作为对 BaseMapper
公用方法的补充,适用于所有 mapper 查询。
对于其他增、删、改、查的要求,如果有相关的需要,都可以按照这个固定套路来实现。
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!