MyBatis-Plus使用动态表名分表查询的实现
作者:彭于晏Yan
本文主要介绍了MyBatis-Plus使用动态表名分表查询,主要是动态修改表名的几种常见场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
动态修改表名的场景通常用于:
- 分表策略:根据不同的条件(如年份、月份、区域等)来选择查询不同的表。
- 多租户系统:根据租户的不同,查询不同的表。
- 历史数据管理:查询历史表的数据时,动态决定表名(例如每年有一个对应的表,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 动态表查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
- MybatisPlus拦截器如何实现数据表分表
- SpringBoot+MybatisPlus实现sharding-jdbc分库分表的示例代码
- SpringBoot+Mybatis-plus+shardingsphere实现分库分表的方案
- Mybatis-Plus集成Sharding-JDBC与Flyway实现多租户分库分表实战
- SQL数据分表Mybatis Plus动态表名优方案
- SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表
- springboot+mybatis-plus基于拦截器实现分表的示例代码
- Mybatis-plus使用TableNameHandler分表详解(附完整示例源码)
- Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 实现分库分表功能
