- 近日公司需要新框架需要兼容旧代码,旧代码用的mybatis手写的动态表名 ,大概是实体类定义一个table字段 然后将table的值传到映射文件中,${table} 这种方式, 研究了一下mp发现可以直接用拦截器替换表名就有了以下代码
1. 3.4.3.4 (最新版)动态表名实现
1.配置类 (官方方式)
@Configuration
@MapperScan("com.cars.ysdd.clts.domain.clts.dao")
public class MybatisPlusConfig {
static List<String> tableList(){
List<String> tables = new ArrayList<>();
tables.add("user");
return tables;
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
String newTable = null;
for (String table : tableList()) {
newTable = RequestDataHelper.getRequestData(table);
if (table.equals(tableName) && newTable!=null){
tableName = newTable;
break;
}
}
return tableName;
});
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
return interceptor;
}
}
2.请求参数传递辅助类
package com.baomidou.mybatisplus.samples.dytablename.config;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import java.util.Map;
public class RequestDataHelper {
private static final ThreadLocal<Map<String, Object>> REQUEST_DATA = new ThreadLocal<>();
public static void setRequestData(Map<String, Object> requestData) {
REQUEST_DATA.set(requestData);
}
public static <T> T getRequestData(String param) {
Map<String, Object> dataMap = getRequestData();
if (CollectionUtils.isNotEmpty(dataMap)) {
return (T) dataMap.get(param);
}
return null;
}
public static Map<String, Object> getRequestData() {
return REQUEST_DATA.get();
}
}
3.使用
@SpringBootTest
class DynamicTableNameTest {
@Resource
private UserMapper userMapper;
@Test
void test() {
RequestDataHelper.setRequestData(new HashMap<String, Object>() {
{
put("user", "user_2018");
}});
for (int i = 0; i < 6; i++) {
User user = userMapper.selectById(1);
System.err.println(user.getName());
}
}
}
2. 3.4.1版
1. 配置类
- 这里的RequestDataHelper 用的是上文的3.4.3.4中的
@Configuration
@MapperScan("com.cars.ysdd.clts.domain.clts.dao")
public class DynamicTableNameHandler {
static List<String> tableList() {
List<String> tables = new ArrayList<>();
tables.add("CR_CZJM");
return tables;
}
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor paginationInterceptor = new MybatisPlusInterceptor();
DynamicTableNameInnerInterceptor dynamicTableNameParser = new DynamicTableNameInnerInterceptor();
dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, TableNameHandler>(2) {
{
for (String table : tableList()) {
put(table, (sql, tableName) -> {
return RequestDataHelper.getRequestData(table) == null ? tableName : RequestDataHelper.getRequestData(table);
});
}
}});
paginationInterceptor.addInnerInterceptor(dynamicTableNameParser);
return paginationInterceptor;
}
}
2. 使用
@Override
public int insert(CrCzjmDO crCzjmDO) {
RequestDataHelper.setRequestData(new HashMap<String, Object>(){
{
put("CR_CZJM","TJFX.CR_CZJM");
}});
return crCzjmMapper.insertSelective(crCzjmDO);
}
3. 3.4 以下版本 (3.1.2 版为例)
1.配置类
@Configuration
public class DynamicTableNameHandler {
public static final String DYNAMIC_TABLE_NAME = "tableName";
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {
{
put("payment", (metaObject, sql, tableName) -> {
Object param = getParamValue(DYNAMIC_TABLE_NAME, metaObject);
if(param == null){
return tableName;
}else {
return param.toString();
}
});
}});
paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
return paginationInterceptor;
}
private Object getParamValue(String title, MetaObject metaObject){
Object originalObject = metaObject.getOriginalObject();
JSONObject originalObjectJSON = JSON.parseObject(JSON.toJSONString(originalObject));
JSONObject boundSql = originalObjectJSON.getJSONObject("boundSql");
try {
JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
return parameterObject.get(title);
}catch (Exception e) {
return null;
}
}
}
2. 实体类示例
- 定义一个与上边配置类中DYNAMIC_TABLE_NAME 的值对应名称的字段(非数据库)
@Data
public class Payment implements Serializable {
private static final long serialVersionUID = 1L;
private String serial;
@TableField(exist = false)
private String tableName;
}
3. 使用
@Override
public List<Payment> selectByTable(String table) {
Payment payment = new Payment();
payment.setTableName(table);
return paymentMapper.select(payment);
}