Mybatis-Plus实现SQL * 的示例
作者:KevinQ 发布时间:2022-05-14 13:55:14
标签: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());
}
}
来源:https://juejin.cn/post/7230746649663520828


猜你喜欢
- 一、字符串:1、访问String中的字符:string本身可看作一个Char数组。string s = "hello world&
- 前言各位精通CRUD的老司机,相信大家在工作中mybatis或者mybatisplus使用的肯定是比较多的,那么大家或多或少都应该对下面的行
- springboot就是简化Spring应用中的初始化配置,快速创建项目而生的。创建springboot项目代开idea,点击File—&g
- 一、开源项目 Javascript .NET地址: http://javascriptdotnet.codeplex.com/ 它是Goog
- 正式版:版本最新但只有14天的体验时间,之后需要激活,激活注册已经不行了,现在需要使用新的方式:首先下载反向代理工具,下载地址:根据系统选择
- Java处理JSON数据有三个比较流行的类库FastJSON、Gson和Jackson。JacksonJackson是由其社区进行维护,简单
- 本文以实例描述了C#实现让窗体永远在窗体最前面显示的方法,具体步骤如下:1、新建一个窗体程序,添加一个Timer以及设置它可用并绑定事件。2
- 项目需要从其他网站获取数据,因为是临时加的需求,在开始项目时没想到需要多数据源于是百度了一下,发现只需要改动一下Spring 的applic
- 欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demo
- Springboot 内置tomcat禁止不安全HTTP方法1、在tomcat的web.xml中可以配置如下内容让tomcat禁止不安全的H
- 问题:在用Java程序进行读写含中文的txt文件时,经常会出现读出或写入的内容会出现乱码。原因其实很简单,就是系统的编码和程序的编码采用了不
- 前言AQS 绝对是JUC的重要基石,也是面试中经常被问到的,所以我们要搞清楚这个AQS到底是什么?骑工作原理是什么?AQS是什么?AQS,A
- 本文实例为大家分享了Android获取设备传感器的具体代码,供大家参考,具体内容如下结果示例:xml代码:<?xml version=
- 本文以实例详述了C#实现Socket通信的解决方法,具体实现步骤如下:1、首先打开VS新建两个控制台应用程序:ConsoleApplicat
- 本文实例讲述了Android桌面插件App Widget用法。分享给大家供大家参考,具体如下:应用程序窗口小部件App Widgets应用程
- 1.官网下载JDK:1.1下载地址:https://www.oracle.com/java/technologies/javase-down
- 一、问题描述今天做了一个C++的类组合的作业,由于是基础小白,编写之后一直出现Id returned 1exit status的情况:网上查
- 本文总结分析了Android7.0版本影响开发的改进。分享给大家供大家参考,具体如下:低电耗模式会对闹铃、GPS 和 Wi-Fi 扫描 产生
- 前言在上一篇文章中,我们分析了Spring中Bean的实例化过程,在结尾我们知道了虽然bean的实例化完成了,但是其中的属性还没有被注入,今
- 从个小例子开始: int[] intArray = new int[]{2,3,6,1,4,5}; Array.Sort(intArray)