MybatisPlus动态修改表名或增加库名

本文介绍了在数据库操作中动态修改表名的需求,特别是在分表和多数据库实例场景下。通过MybatisPlus,作者提供了一个配置类来实现动态修改表名,包括核心的DynamicTableNameParser和ITableNameHandler类的使用。文章还提出了进一步优化的方案,如按需分目录存放mapper接口,使用静态对象存储表名处理映射,并在Interceptor中动态设置处理映射,以避免硬编码表名。

背景

 在数据库操作过程中,经常有修改表名的需求,例如:分表时,修改表名加上分表前后缀;多数据库一个实例,表名前面加上库名,实现本地跨库事务等等。
 我用到的场景是后者,动态加库名。由于使用了MybatisPlus,整个开发过程中不会自己写sql,也没办法通过硬编码修改表名。

解决方案

 MybatisPlus中只需要一个配置类即可自定义,动态修改表名,代码如下:

@Configuration
public class MybatisPlusConfig {
    List<String> tables = Lists.newArrayList("user","class");
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
        dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>() {{
            tables.forEach(tableTitle -> put(tableTitle,(metaObject, sql, tableName) -> "db01." + tableName ));
        }});
        paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
        return paginationInterceptor;
    }
}

代码说明:
 两个核心类:DynamicTableNameParser 动态解析表名,ITableNameHandler 表名处理。
  DynamicTableNameParser会根据当前sql的tableName获取对应的ITableNameHandler,上面用拉姆达表达式,实现了ITableNameHandler中的dynamicTableName方法,拼上前缀。
ITableNameHandler源码如下:


    /**
     * 表名 SQL 处理
     *
     * @param metaObject 元对象
     * @param sql        当前执行 SQL
     * @param tableName  表名
     * @return
     */
    default String process(MetaObject metaObject, String sql, String tableName) {
        String dynamicTableName = dynamicTableName(metaObject, sql, tableName);
        if (null != dynamicTableName && !dynamicTableName.equalsIgnoreCase(tableName)) {
            // 直接替换字符串对于 SQL 操作是不那么好做,这里修复只能尽可能的保证处理没问题
            String regex = "(?<=\\s)\\Q" + tableName + "\\E(?=\\s)";
            return sql.replaceAll(regex, dynamicTableName);
        }
        return sql;
    }

    /**
     * 生成动态表名,无改变返回 NULL
     *
     * @param metaObject 元对象
     * @param sql        当前执行 SQL
     * @param tableName  表名
     * @return String
     */
    String dynamicTableName(MetaObject metaObject, String sql, String tableName);

进一步优化方案

 这里的方案,哪些表需要重写表名,需要硬编码到代码中,自定义表名列表。如何做成自动的呢?
 1. 将需要使用不同表的mapper接口,分目录存放。
 2. 自定义的tableNameHandlerMap,保存为静态对象,随时可以修改。
 3. 在mybatis的Interceptor中,根据当前sql的目录路径和表名,动态设置tableNameHandlerMap。
 目前项目只用到了几张表,优化方案,暂未提供代码例子。有更好方案,欢迎评论区交流,谢谢。

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值