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

本文介绍了如何在Spring Boot项目中利用Mybatis-Plus进行动态表名的处理,分别展示了两种方案:一是通过分页拦截器PaginationInterceptor动态处理表名,二是使用MybatisPlusInterceptor配合DynamicTableNameInnerInterceptor解决动态表名与分页拦截器的冲突问题。内容包括保存和查询操作,并提供了具体业务场景和解决方案的详细说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

保存

查询:

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dengrz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值