因為表的數據太大了,有的項目會進行分表存儲。例如日志表,一般都是按時間區分,表名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解析器同樣有效。