MyBatis-Plus 动态表名SQL解析器的实现
一、引言
先来说下动态名表在什么场景下需要使用呢?
拿小编的实际项目来说,小编公司手里掌握着国内各个部分地区的医院患者数据,那么一个医院的患者的数据流量肯定是很大的,这个时候如果全部放在同一张表中,那么可想而知数据量的庞大。所以数据库设计的时候可以一家医院对应一张表,分开来存储,表中的列名都是一样的,只是表名不同。
或者还可以做日志的存储,日志数据量也是很大的,可以分一个月对应一张表,比如:log_201907、log_201908等等之类的。
二、具体实现
动态表名SQL解析器也是基于MP分页插件来实现的,代码如下:
packagecom.example.demo.config;
importcom.baomidou.mybatisplus.core.parser.ISqlParser;
importcom.baomidou.mybatisplus.core.parser.ISqlParserFilter;
importcom.baomidou.mybatisplus.core.parser.SqlParserHelper;
importcom.baomidou.mybatisplus.extension.parsers.DynamicTableNameParser;
importcom.baomidou.mybatisplus.extension.parsers.ITableNameHandler;
importcom.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
importcom.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
importcom.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
importcom.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
importcom.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
importnet.sf.jsqlparser.expression.Expression;
importnet.sf.jsqlparser.expression.StringValue;
importorg.apache.ibatis.mapping.MappedStatement;
importorg.apache.ibatis.reflection.MetaObject;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.Profile;
importjava.util.*;
/**
*@Auther:IT贱男
*@Date:2019/6/1215:06
*@Description:MybatisPlus配置类
*/
@Configuration
publicclassMyBatisPlusConfig{
/**
*分页插件
*
*@return
*/
@Bean
publicPaginationInterceptorpaginationInterceptor(){
PaginationInterceptorpaginationInterceptor=newPaginationInterceptor();
//创建SQL解析器集合
ListsqlParserList=newArrayList<>();
//动态表名SQL解析器
DynamicTableNameParserdynamicTableNameParser=newDynamicTableNameParser();
MaptableNameHandlerMap=newHashMap<>();
//Map的key就是需要替换的原始表名
tableNameHandlerMap.put("sys_user",newITableNameHandler(){
@Override
publicStringdynamicTableName(MetaObjectmetaObject,Stringsql,StringtableName){
//自定义表名规则,或者从配置文件、request上下文中读取
//假设这里的用户表根据年份来进行分表操作
Datedate=newDate();
Stringyear=String.format("%tY",date);
//返回最后需要操作的表名,sys_user_2019
return"sys_user_"+year;
}
});
dynamicTableNameParser.setTableNameHandlerMap(tableNameHandlerMap);
sqlParserList.add(dynamicTableNameParser);
paginationInterceptor.setSqlParserList(sqlParserList);
returnpaginationInterceptor;
}
}
代码演示:MP会针对配置的表名做动态解析,从sql中可以看出表名已经替换成sys_user_2019了。
@Test
publicvoidselect(){
Listusers=userMapper.selectList(Wrappers.lambdaQuery().eq(User::getAge,18));
users.forEach(System.out::println);
}
INFOStartedUserMapperTestin3.409seconds(JVMrunningfor4.233)
DEBUG==>Preparing:SELECTid,login_name,name,password,email,salt,sex,age,phone,user_type,status,organization_id,create_time,update_time,version,tenant_idFROMsys_user_2019WHEREsys_user_2019.tenant_id='jiannan'ANDis_delete='0'ANDage=?
DEBUG==>Parameters:18(Integer)
三、注意细节
细节一:如果自定义规则的表名返回为空,则会按照实际的表名来处理。
细节二:如果配置了多租户SQL解析器,过滤了特定的sql,则也会按照实际表名来处理。
如下代码使用了@SqlParser注解来过滤这条sql不需要加租户ID,执行这条sql的时候同样也会把动态表名SQL解析也会过滤掉,按照实际表名处理,MP可能后续版本会进行改进。
/** **用户Mapper接口 *
* *@authorIT贱男 *@since2019-06-14 */ publicinterfaceUserMapperextendsBaseMapper{ /** *自定Wrapper修改 * *@paramuserWrapper条件构造器 *@paramuser修改的对象参数 *@return */ @SqlParser(filter=true) intupdateByMyWrapper(@Param(Constants.WRAPPER)Wrapper userWrapper,@Param("user")Useruser); }
到此这篇关于MyBatis-Plus动态表名SQL解析器的实现的文章就介绍到这了,更多相关MyBatis-Plus动态表名SQL解析器内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。