mybatis-plus动态表名实现

mybatis-plus动态表名实现

1.使用场景

一个mybatis entity 对应多张表(表明不同的表–> 多张表结构一致只有表名称不同),在使用时,可以动态映射表名称。
比如:按照时间分表,某些业务冷热数据分离后数据存在不同的表中等

2.一定要时常注意工具的更新,不吃亏

因为工作需要,最近需要实现一个类似如下业务等功能交互:
在这里插入图片描述
简单的描述就是:有一部分的表数据,采用了外部同步的模式,同步到了doris中,在业务中采用双数据源的方式,数据写在mysql,读走doris (此处不考虑数据同步的延迟问题 ,这是个大问题,但我们这篇文章先不考虑这个问题)。
要实现上面的方案,需要解决以下几个问题:

  1. 双数据源的问题
  2. doris/mysql中库和表的名称不一致(例如:上图绿色打底的表,在mysql和doris中表的结构一致,但在mysql中库.表名为 : databaseA.tableA ,在doris中则为 databaseB.ods_tableB_s)

在之前项目研究中,因为有自己去自定义dao层mapper的方法,mybatis表中的方法对应的sql在项目启动时就已经生成好了对应的sql模板,在程序运行中,只是用参数代替即可。
在这里插入图片描述
例如上图,因为我之前用的mybatis-plus 的版本比较低,在生成模板时实际上就已经确定了表的名称。这就导致了无法在使用的时候重新替换。为了实现这个功能,自己实现的时候也是一直往我如何在生成模板语句的时候就直接把我想要的表名替换替换进去。 在实现的差不多的时候,同事来了一句,mybatis-plus不是支持的吗? hhhh,所以说,还是要去关注一下你在项目中所用到的jar包的迭代更新哦,会发现很多,然后开始偷懒。
在这里插入图片描述

3.对mybatis-plus进行升级

我把版本从:3.3.0 升级到了 3.4.3.2
启动项目的时候发现服务启动失败了,着急嘿~

然后在解决问题的过程中发现时因为jar包冲突了 。
然后发现了idea中一个很好使用的工具【在pom.xml文件中要,右击鼠标进入到Maven -> show dependence 】可以很直观的看见冲突法jar包,然后去解决对应的冲突就可以了 (这里不多说了,给大家一个学习链接传送门:https://blog.csdn.net/daerzei/article/details/82344569)

4.将原来的mybatis的插件配置调整成新版本的,并添加上动态表名的模块

4.1 调整mybatis plus 配置
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        //添加上自己实现的表名处理器DayRecordTableNameHandler
        dynamicTableNameInnerInterceptor.setTableNameHandler(new DayRecordTableNameHandler());
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);

        return interceptor;
    }
4.2 自定义表名称处理器

结合threadlocal 来确定对对应的业务逻辑使用什么表名称(我这里是利用将数据源信息放入到threadlocal中,然后来映射不同的表名称),下面的代码示例是一个简化版:

public class DayRecordTableNameHandler implements TableNameHandler {
    private static final Logger log = LoggerFactory.getLogger(DayRecordTableNameHandler.class);

    public DayRecordTableNameHandler(){
    }

    @Override
    public String dynamicTableName(String sql, String tableName) {
        Object dataSource = HnThreadLocal.get(SystemConstants.DATASOURCE);
        if(Objects.isNull(dataSource)){
            return tableName;
        }
        if(Objects.equals(tableName,"zsh_day_record")){
            int dataSourceIntValue = (int)dataSource;
            if(Objects.equals(dataSourceIntValue,1)){
                log.info("表名替换:"+tableName+"--->sql:ods_zsh_day_record_s");
                return "ods_zsh_day_record_s";
            }
        }
        return tableName;
    }

}
4.3 利用AOP切换数据源

这里想省略了,多数据源用的是dynamic-datasource-spring-boot-starter
AOP监听多是 @DS ,依据注解value来判断数据源是不是走doris

5.运行一下

成功运行

6. 需要注意的地方

  1. threadlocal 中的数据在aop中最好自己释放掉 ,spring是用的线程池,如果不清理掉会影响线程下次使用的程序
  2. 这是个草稿实现,因为前面强调的数据同步模块,是需要考虑进去的,继续摸索啦~~~
MyBatis-Plus是一个基于MyBatis的增强工具,它提供了许多方便的功能,其中包括动态表的支持。通过使用MyBatis-Plus提供的DynamicTableNameInnerInterceptor拦截器,可以在运行时动态替换SQL语句中的表。 使用MyBatis-Plus实现动态表有以下几个作用: 1. 实现数据分表或数据分区:可以根据特定的规则生成动态表,例如按照时间分表或按照业务冷热数据分离后将数据存储在不同的表中。 2. 隐藏数据表:在某些情况下,为了安全或其他目的,可能需要隐藏数据库的表。使用DynamicTableNameInnerInterceptor可以将表进行动态替换,从而达到隐藏表的效果。 3. 提高系统的可扩展性:通过动态表解析器,可以将不同的数据表或数据库实例进行解耦,从而提高系统的可扩展性。例如,可以将一个大型的数据库系统分成多个小型的数据库实例,然后通过动态表解析器将SQL语句分发到不同的实例中。 4. 简化代码开发:使用DynamicTableNameInnerInterceptor,可以避免在代码中硬编码SQL语句中的表,从而简化代码的开发和维护。特别是在应对表结构频繁变化的场景下,使用该拦截器能够更快速地实现变更,从而降低维护成本。 因此,通过使用MyBatis-Plus的DynamicTableNameInnerInterceptor拦截器,可以实现mybatis-plus动态表的功能,并带来诸多好处。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【mybatis-plus系列】动态表](https://blog.csdn.net/qyj19920704/article/details/130010294)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [mybatis-plus动态表实现](https://blog.csdn.net/zhangsuhua0702/article/details/122807303)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值