基于MyBatis插件实现动态表名解决多环境单一数据库问题

业务场景

在为某新能源汽车厂商进行我司系统私有化部署时,在预演环境和生产环境中,客户仅提供了一个 MySQL 数据库实例。为了确保数据隔离并避免不同环境之间的数据冲突,常规做法是为每个环境创建独立的表(如通过添加环境前缀或后缀)。

然而,如果每次切换环境都需要手动修改 SQL 或配置文件中的表名,不仅效率低下,而且容易出错。为此,小编利用 MyBatis 插件机制 实现了动态表名替换,从而优雅地解决了多环境共用数据库的问题。

解决方案

java 复制代码
/**
 * 动态表名工具参数
 *
 * @author 言安
 * @date 2025/3/20 14:37
 */
@Data
@Component
@ConfigurationProperties(prefix = SpongeDynamicTableNameProperties.PREFIX)
public class SpongeDynamicTableNameProperties {

    public static final String PREFIX = "sponge.dynamic";

    /**
     * 是否开启
     */
    private Boolean enable = Boolean.FALSE;
    /**
     * 默认表名后缀
     */
    private String defaultTableNameSuffix;
    /**
     * 表名后缀映射(key:表名, value: 后缀)
     * 优先取表名后缀映射,取不到取 defaultTableNameSuffix
     */
    private Map<String, String> tableNameSuffixMap;
}
java 复制代码
/**
 * 动态表名处理器
 *
 * @author 言安
 * @date 2025/3/20 13:41
 */
@Component
public class SpongeDynamicTableNameHandler implements TableNameHandler {


    // 默认后缀
    private final static String DEFAULT_SUFFIX = "_test";

    @Resource
    private SpongeDynamicTableNameProperties spongeDynamicTableNameProperties;

    @Override
    public String dynamicTableName(String sql, String tableName) {
        String suffix = DEFAULT_SUFFIX;
        if (spongeDynamicTableNameProperties != null) {
            if (spongeDynamicTableNameProperties.getDefaultTableNameSuffix() != null) {
                suffix = spongeDynamicTableNameProperties.getDefaultTableNameSuffix();
            }
            if (spongeDynamicTableNameProperties.getTableNameSuffixMap() != null && spongeDynamicTableNameProperties.getTableNameSuffixMap().containsKey(tableName)) {
                suffix = spongeDynamicTableNameProperties.getTableNameSuffixMap().get(tableName);
            }
        }
        return StringUtil.isBlank(suffix) ? tableName : tableName + suffix;
    }
}
java 复制代码
/**
 * MybatisPlus配置类
 *
 * @author 言安
 * @date 2025/3/20 13:41
 */
@Configuration
@EnableTransactionManagement
public class MybatisPlusConfiguration {

    @Resource
    private SpongeDynamicTableNameProperties spongeDynamicTableNameProperties;

    @Resource
    private SpongeDynamicTableNameHandler myTableNameHandler;

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        if (spongeDynamicTableNameProperties != null && Boolean.TRUE.equals(spongeDynamicTableNameProperties.getEnable())) {
            // 动态表名插件
            DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
            dynamicTableNameInnerInterceptor.setTableNameHandler(myTableNameHandler);
            interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        }
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
相关推荐
博一波2 分钟前
Redis 集群:连锁银行的 “多网点智能协作系统”
数据库·redis·缓存
HashData酷克数据8 分钟前
官宣:Apache Cloudberry (Incubating) 2.0.0 发布!
数据库·开源·apache·cloudberry
秋难降8 分钟前
SQL 索引突然 “罢工”?快来看看为什么
数据库·后端·sql
TDengine (老段)38 分钟前
TDengine 时间函数 TODAY() 用户手册
大数据·数据库·物联网·oracle·时序数据库·tdengine·涛思数据
码界奇点1 小时前
KingbaseES一体化架构与多层防护体系如何保障企业级数据库的持续稳定与弹性扩展
数据库·架构·可用性测试
悟乙己1 小时前
数据科学家如何更好地展示自己的能力
大数据·数据库·数据科学家
皆过客,揽星河1 小时前
mysql进阶语法(视图)
数据库·sql·mysql·mysql基础语法·mysql进阶语法·视图创建修改删除
tuokuac2 小时前
Redis 的相关文件作用
数据库·redis·缓存
鹧鸪云光伏与储能软件开发3 小时前
投资储能项目能赚多少钱?小程序帮你测算
运维·数据库·小程序·光伏·光伏设计软件·光伏设计
2301_779503765 小时前
MySQL主从同步--主从复制进阶
数据库·mysql