利用Mybatis Plus实现一个SQL拦截器

 更新时间:2023年05月09日 14:08:04   作者:KevinQ  
SQL拦截器是一种用于拦截和修改Mybatis执行的SQL语句的工具,通过使用SQL拦截器,开发人员可以在执行SQL语句之前或之后对其进行修改或记录,本文就来借助一下Mybatis-Plus实现一个SQL拦截器吧

起源

最近公司要做多租户,Mybatis-Plus的多租户插件很好用,但是有一个场景是:字典表或者某些数据表,一些数据需要在各个租户之间共享,而数据表本身又同时要实现多租户数据隔离,比如字典表:性别等“男”/“女”基础数据。

SQL拦截器是一种用于拦截和修改Mybatis执行的SQL语句的工具。通过使用SQL拦截器,开发人员可以在执行SQL语句之前或之后对其进行修改或记录,从而更好地控制和优化数据库操作。例如MyBatis-Plus的基础分页插件、多租户插件就是SQL拦截器,那么,我们是否可以实现自己的SQL拦截器呢?

答案当然是肯定的。

实现拦截器接口InnerInterceptor

InnerInterceptor 这个接口是MyBaitsPlus的拦截器接口类,实现它之后,并且通过MybatisPlusInterceptor配置后,就可以实现SQL执行拦截。

MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

// 多租户拦截器
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantDatabaseInterceptor(tenantProperties)));
// 多租户部分表数据共享拦截器
interceptor.addInnerInterceptor(new TenantDatabaseShareInterceptor(new TenantShareHandlerImpl(tenantProperties)));

那么如何实现该接口以及修改SQL呢?

下面是一个样例:

import com.baomidou.mybatisplus.core.interceptor.InnerInterceptor;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptorChain;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.Select;

public class MyInterceptor implements InnerInterceptor {
    @Override
    ```
    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        if (InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) return;
        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
        mpBs.sql(parserSingle(mpBs.sql(), null));
    }

}

通过修改beforeQuery函数中的代码,即可修改执行的SQL。

修改sql常用的工具类

JsqlParserSupport该类用于解析与修改SQL,并且MybatisPlus的多租户插件更是直接继承了该类。 CCJSqlParserUtil是JSqlParser中用于解析SQL语句的工具类。它提供了一些静态方法,可以将SQL语句解析为Statement对象、Select对象、Update对象、Insert对象、Delete对象等。

常用的类还有Expression, Statement等类。

例如,使用Expression实现一个IN语句:

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
import net.sf.jsqlparser.expression.operators.relational.NamedParameter;
import net.sf.jsqlparser.expression.operators.relational.SubSelect;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;

public class JSqlParserExample {
    public static void main(String[] args) throws Exception {
        // IN语句
        InExpression inExpr = new InExpression();
        inExpr.setLeftExpression(CCJSqlParserUtil.parseExpression("age"));
        ItemsList valueList = new MultiExpressionList();
        ((MultiExpressionList) valueList).addExpressions(new LongValue(18), new LongValue(21), new LongValue(30));
        inExpr.setItemsList(valueList);
        System.out.println(inExpr.toString());

        // 子查询
        InExpression subqueryInExpr = new InExpression();
        subqueryInExpr.setLeftExpression(CCJSqlParserUtil.parseExpression("age"));
        SubSelect subquery = new SubSelect();
        subquery.setSelectBody(CCJSqlParserUtil.parse("SELECT age FROM users WHERE country = 'US'"));
        subqueryInExpr.setRightExpression(subquery);
        System.out.println(subqueryInExpr.toString());
    }
}

到此这篇关于利用Mybatis Plus实现一个SQL拦截器的文章就介绍到这了,更多相关Mybatis Plus SQL拦截器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring整合多数据源实现动态切换的实例讲解

    Spring整合多数据源实现动态切换的实例讲解

    下面小编就为大家带来一篇Spring整合多数据源实现动态切换的实例讲解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 浅析Java中comparator接口与Comparable接口的区别

    浅析Java中comparator接口与Comparable接口的区别

    本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧
    2016-10-10
  • 解决Intellij IDEA运行报Command line is too long的问题

    解决Intellij IDEA运行报Command line is too long的问题

    这篇文章主要介绍了解决Intellij IDEA运行报Command line is too long的问题,本文通过两种方案给大家详细介绍,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • Eclipse开发JavaWeb项目配置Tomcat的方法步骤

    Eclipse开发JavaWeb项目配置Tomcat的方法步骤

    本文主要介绍了Eclipse开发JavaWeb项目配置Tomcat的方法步骤,首先介绍eclipse开发JavaWeb项目需要配置的相关环境,使用tomcat软件在本地搭建服务器,然后再在eclipse环境下配置tomcat,感兴趣的可以了解一下
    2021-08-08
  • Java排序算法之桶排序算法解析

    Java排序算法之桶排序算法解析

    这篇文章主要介绍了Java排序算法之桶排序算法解析,桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作原理是将数组分到有限数量的桶子里,每个桶子再个别排序,有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序,需要的朋友可以参考下
    2023-10-10
  • java实现发送邮件功能

    java实现发送邮件功能

    这篇文章主要为大家详细介绍了java实现发送邮件功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • Java中注解与原理分析详解

    Java中注解与原理分析详解

    注解即标注与解析,在Java的代码工程中,注解的使用几乎是无处不在,甚至多到被忽视。本文就来和大家详细说说Java中注解的原理与实现,需要的可以参考一下
    2022-11-11
  • 解决java中mybatis报错:org.apache.ibatis.binding.BindingException:Invalid bound statement(not found):xx问题

    解决java中mybatis报错:org.apache.ibatis.binding.BindingException:

    这篇文章主要介绍了解决java中mybatis报错:org.apache.ibatis.binding.BindingException:Invalid bound statement(not found):xx问题,具有很好的参考价值,希望对大家有所帮助
    2024-03-03
  • Java8 将一个List<T>转为Map<String,T>的操作

    Java8 将一个List<T>转为Map<String,T>的操作

    这篇文章主要介绍了Java8 将一个List<T>转为Map<String, T>的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • SpringBoot整合EasyExcel的完整过程记录

    SpringBoot整合EasyExcel的完整过程记录

    easyexcel是阿里巴巴旗下开源项目,主要用于Excel文件的导入和导出处理,下面这篇文章主要给大家介绍了关于SpringBoot整合EasyExcel的完整过程,需要的朋友可以参考下
    2021-12-12

最新评论