Mybatis-Plus实现SQL * 的示例
作者:KevinQ 时间:2022-05-14 13:55:14
起源
最近公司要做多租户,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
标签:Mybatis-Plus,SQL, ,
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
C#中循环语句:while、for、foreach的使用
2022-05-01 02:42:55
Java中过滤器 (Filter) 和 拦截器 (Interceptor)的使用
2023-07-07 00:20:28
![](https://img.aspxhome.com/file/2023/3/63453_0s.png)
maven中下载jar包源码和javadoc的命令介绍
2023-07-27 04:41:01
![](https://img.aspxhome.com/file/2023/3/61033_0s.png)
Java实现分页代码
2023-08-05 08:14:47
linux环境下java程序打包成简单的hello world输出jar包示例
2023-11-26 11:11:37
![](https://img.aspxhome.com/file/2023/8/60378_0s.png)
Spring Security中的Servlet过滤器体系代码分析
2023-03-23 19:05:34
![](https://img.aspxhome.com/file/2023/3/92553_0s.png)
spring boot中配置hikari连接池属性方式
2022-11-13 06:06:44
Java实现在线聊天室(层层递进)
2022-06-13 11:03:47
![](https://img.aspxhome.com/file/2023/3/91093_0s.jpg)
Android SDK Manager解决更新时的问题 :Failed to fetch URL...
2023-03-17 23:23:36
Java之Algorithm_analysis案例详解
2022-03-07 01:34:50
Spring中集成Groovy的四种方式(小结)
2023-07-11 16:36:53
![](https://img.aspxhome.com/file/2023/7/73117_0s.jpg)
C# WPF数据绑定模板化操作的完整步骤
2023-05-20 15:44:50
springboot如何读取配置文件到静态工具类
2023-11-28 04:44:54
![](https://img.aspxhome.com/file/2023/6/60036_0s.png)
SpringCloud Eureka的使用教程
2022-03-23 22:30:59
![](https://img.aspxhome.com/file/2023/8/70348_0s.png)
Java操作Mongodb数据库实现数据的增删查改功能示例
2023-11-25 00:02:05
简述Java图像倾斜方法及实例 <font color=red>原创</font>
2023-08-16 09:38:47
使用springboot aop来实现读写分离和事物配置
2022-10-29 11:43:07
![](https://img.aspxhome.com/file/2023/6/69086_0s.jpg)
WPF在VisualTree上增加Visual
2023-03-20 00:06:47
![](https://img.aspxhome.com/file/2023/3/88423_0s.png)
C#Winform窗口移动方法
2023-04-10 04:46:18
Java封装、继承、多态三大特征的理解
2023-07-16 14:26:46