动态修改表名的场景通常用于:
- 分表策略:根据不同的条件(如年份、月份、区域等)来选择查询不同的表。
- 多租户系统:根据租户的不同,查询不同的表。
- 历史数据管理:查询历史表的数据时,动态决定表名(例如每年有一个对应的表,table_2021, table_2022 等)。
1. 引入依赖
<dependency>
<groupid>com.baomidou</groupid>
<artifactid>mybatis-plus-boot-starter</artifactid>
<version>3.5.3</version>
</dependency>
注意:版本须使用3.5.3以上,否则无法使用dynamictablenameinnerinterceptor类中的settablenamehandler方法
2. mybatis-plus配置
@configuration
@slf4j
public class mybatisplusconfig {
@bean
public mybatisplusinterceptor mybatisplusinterceptor() {
mybatisplusinterceptor mybatisplusinterceptor = new mybatisplusinterceptor();
// 数据权限
//mybatisplusinterceptor.addinnerinterceptor(new datafilterinterceptor());
// 乐观锁
mybatisplusinterceptor.addinnerinterceptor(new optimisticlockerinnerinterceptor());
// 防止全表更新与删除
mybatisplusinterceptor.addinnerinterceptor(new blockattackinnerinterceptor());
//动态表名
dynamictablenameinnerinterceptor dynamictablenameinnerinterceptor = new dynamictablenameinnerinterceptor();
dynamictablenameinnerinterceptor.settablenamehandler((sql, tablename) -> { //匿名内部类
string tenant = tenantcontext.tenant_data.get();
// 如果不为空,使用动态表名。
if (stringutils.isnotblank(tenant) && tenantcontext.containstablename(tablename)) {
log.info("dynamictablename -- >tablename={}, tenant={}",tablename, tenant);
return tablename + "_" + tenant;
}
return tablename;
});
mybatisplusinterceptor.addinnerinterceptor(dynamictablenameinnerinterceptor);
// 分页插件
mybatisplusinterceptor.addinnerinterceptor(new paginationinnerinterceptor());
return mybatisplusinterceptor;
}
}
3. tenantcontext 类:租户上下文管理器
public class tenantcontext {
// 需要替换的动态表名
public static threadlocal<string> tenant_data = new threadlocal<>();
//用于记录哪些表可以使用该动态表名处理器
private static list<string> tablenames = arrays.aslist("test_user");
//设置请求线程的租户数据
public static void settenantdata(string tenant) {
tenant_data.set(tenant);
}
//删除当前请求线程的租户数据
public static void removeyeardata() {
tenant_data.remove();
}
public static boolean containstablename(string tablename) {
if (tablenames.contains(tablename)) {
return true;
}
return false;
}
}
4. 实体类
@data
@tablename("test_user")
public class testuser implements serializable {
private string id;
private string name;
private string managerid;
private string salary;
private string age;
private string departid;
private string remark;
private string province;
}
5. 具体实现
@restcontroller
@slf4j
public class testcontroller {
@resource
private itestuserservice testuserservice;
@getmapping("/selectlist")
public list<testuser> selectlist(@requestparam string tenant) {
return testuserservice.selectlist(tenant);
}
}
public interface itestuserservice extends iservice<testuser> {
list<testuser> selectlist(string tenant);
}
@service
public class testuserserviceimpl extends serviceimpl<testusermapper, testuser> implements itestuserservice {
@overridejava
public list<testuser> selectlist(string tenant) {
tenantcontext.settenantdata(tenant);
wrapper<testuser> querywrapper = new querywrapper<>();
return basemapper.selectlist(querywrapper);
}
}
到此这篇关于mybatis-plus使用动态表名分表查询的实现 的文章就介绍到这了,更多相关mybatis-plus 动态表查询内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论