【Mybatis-Plus进阶学习(七)】动态表名SQL解析器
因为表的数据太大了,有的项目会进行分表存储。例如日志表,一般都是按时间区分,表名xxx_年_月;还有的业务表针对不同机构,一个机构一个表 ,表命_xxxid。这些表的字段都是一样的,不同的是内容和表名。当我们需要操作表的时候,可能需要根据业务和需求的不同,操作不同的表,这时候我们就需要动态的进行表名的拼接。虽然市面上也有一些分库分表的插件,但是视频的作者并不推荐。
动态表名的简单使用
动态表名也是要写在分页插件中的,和多租户插件相同。DynamicTableNameParser 必须在MP 3.1.2版本后才能用,3.1.2之前的动态表名操作不一样。
第一步:配置动态表名SQL解析器
public static ThreadLocal<String> myTalbeName = new ThreadLocal<>();
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
ArrayList<ISqlParser> sqlParsers = new ArrayList<>();
DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
Map<String, ITableNameHandler> tableNameHandlerMap = new HashMap<>();
tableNameHandlerMap.put("user", new ITableNameHandler() {
@Override
public String dynamicTableName(MetaObject metaObject, String sql, String tableName) {
//返回替换后的表名
return myTalbeName.get();
}
});
dynamicTableNameParser.setTableNameHandlerMap(tableNameHandlerMap);
sqlParsers.add(dynamicTableNameParser);
paginationInterceptor.setSqlParserList(sqlParsers);
//过滤方法
paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
@Override
public boolean doFilter(MetaObject metaObject) {
MappedStatement mappedStatement = SqlParserHelper.getMappedStatement(metaObject);
if ("com.fang.dao.UserMapper.selectById".equals(mappedStatement.getId())) {
return true;
}
return false;
}
});
return paginationInterceptor;
}
第二步:测试
@Test
public void query() {
MybatisConfig.myTalbeName.set("user_2019");
List<User> list = userMapper.selectList(null);
}
运行测试,会发现报错,因为没有user_2019这张表。
注意事项
- 如果没有给MybatisConfig.myTalbeName赋值,dynamicTableName返回值为空,不会进行表名的替换。
- SqlParserFilter对动态表名SQL解析器同样有效。
- @SqlParser(filter = true)对动态表名SQL解析器同样有效。