利用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拦截器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
将ResultSet中得到的一行或多行结果集封装成对象的实例
这篇文章主要介绍了将ResultSet中得到的一行或多行结果集封装成对象的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-05-05
java fastjson传输long数据却接收到了int的问题
这篇文章主要介绍了java fastjson传输long数据却接收到了int的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-01-01
IDEA社区版创建spring boot项目的安装插件的图文教程
这篇文章主要介绍了IDEA社区版创建spring boot项目的安装插件,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-11-11
springboot+dubbo启动项目时报错 zookeeper not connect
这篇文章主要介绍了springboot+dubbo项目启动项目时报错 zookeeper not connected的问题,本文给大家定位问题及解决方案,结合实例代码给大家讲解的非常详细,需要的朋友可以参考下2023-06-06


最新评论