目录
动态处理方案二:使用MybatisPlusInterceptor处理:
保存
项目中使用了 MyBatis-Plus
简化开发,在项目中,对数据库表的操作,可以通过在数据表实体类中添加@TableName("table_name")
来指定该实体所对应的表,如下:
@Data
@TableName("publictable")
public class AutoDataTable implements Serializable {
private static final long serialVersionUID = 1L;
}
在业务中有这么个需求,在User表添加的时候,同时要对另一张表today_user进行添加 ,user 表和 today_user 表的表结构是一样的,只是一张是总表,一张是当日表。由于总表数据量过大,才加了today_user 这张表方便某个业务查询,以上是业务背景。
由于使用了@TableName("publictable") 注解,指定了表名,想要插入到 viechle_test无法使用AutoDataTable这个实体类,方法如下:
@Data
@TableName("publictable")
public class AutoDataTable implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用于区分入库表名
*/
@TableField(exist = false)
private String tableName;
}
业务代码:
private void arrayIdToObject(JSONObject jsonobejct, List<AutoDataTable> list,
String tableName) {
AutoDataTable autoDataTable = new AutoDataTable();
autoDataTable.setLon(jsonobejct.getString("lon"));
autoDataTable.setLat(jsonobejct.getString("lat"));
autoDataTable.setGtm(jsonobejct.getString("gtm"));
autoDataTable.setTableName(tableName);
list.add(autoDataTable);
jsonobejct = null;
autoDataTable = null;
}
查询:
QueryWrapper<AutoDataTable> qw = new QueryWrapper();
qw.between("gtm", this.strReplace(at.getStartTime()), this.strReplace(at.getEndTime()));
DynamicTableNameHandler.setDynamicTableName(tableName);
List<AutoDataTable> list = autoDataTableMapper.selectList(qw);
动态处理方案一:使用分页拦截器动态表名处理:
@Configuration
public class DynamicTableNameHandler {
private static ThreadLocal<String> table = new ThreadLocal<>();
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {
{
put(CommonConstant.PUBLIC_TABLE_NAME, (metaObject, sql, tableName) -> {
String dynamicTableName = getDynamicTableName(metaObject);
if (StringUtils.isEmpty(dynamicTableName)){
return table.get();
}else{
return dynamicTableName;
}
});
}});
paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
return paginationInterceptor;
}
/**
* 获取元数据里的动态表名
* @param metaObject 元数据对象
* @return 表名
*/
private String getDynamicTableName(MetaObject metaObject){
Object originalObject = metaObject.getOriginalObject();
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(originalObject));
JSONObject boundSql = jsonObject.getJSONObject("boundSql");
JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
return String.valueOf(parameterObject.get(CommonConstant.Dynamic_Table_Name));
}
public static void setDynamicTableName(String tableName){
table.set(tableName);
}
}
动态处理方案二:使用MybatisPlusInterceptor处理:
因自己使用PaginationInterceptor 分页拦截器方案处理动态表名与原有分页拦截器冲突,然后使用MybatisPlusInterceptor与DynamicTableNameInnerInterceptor的方案二成功解决冲突,完整代码配置代码如下:
@Configuration
public class DynamicTableNameHandler {
private static ThreadLocal<String> table = new ThreadLocal<>();
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
HashMap<String, TableNameHandler> map = new HashMap<String, TableNameHandler>(2) {
{
put(CommonConstant.PUBLIC_TABLE_NAME, (sql, tableName) -> {
return table.get();
});
}};
dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
return interceptor;
}
//设置表名
public static void setDynamicTableName(String tableName){
table.set(tableName);
}
}
注:配置中的CommonConstant.PUBLIC_TABLE_NAME参数是实体类AutoDataTable中@TableName("publictable")的默认表名publictable