MyBatis-Plus 实体类实现动态表名的保存与查询

目录

保存

查询:

动态处理方案一:使用分页拦截器动态表名处理:

动态处理方案二:使用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

Guess you like

Origin blog.csdn.net/Dengrz/article/details/121563920