SpringBoot 集成 MybatisPlus 十一——SQL注入器

2023-11-15 21:47:54 浏览数 (3)

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腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞