基于Mybatis拦截器实现动态修改sql语句

因新业务需求更换数据库名称,代码中含原数据库名的SQL语句执行报错。可使用Mybatis拦截器动态修改SQL语句,还需在配置文件中注入Map对象并进行application.yml配置,以将SQL语句中的数据库名替换为新名称。

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

业务背景

由于新业务需要,数据库名称要更换,代码中存在许多数据库名.表明的SQL语句,如:db.user,更换db名称后原代码执行报错,需将SQL语句db名字换为新的数据库名称.

使用Mybatis拦截器实现动态修改sql语句
@Component
@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class, Integer.class })})
public class MybatisInterceptor implements Interceptor {

    //注入配置文件中定义的全局数据库名称
    @Autowired
    ScmGobalDbDefinition scmGobalDbDefinition;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
        String sql = handler.getBoundSql().getSql().toLowerCase();
        Map<String, String> scmDbs = scmGobalDbDefinition.getScmDbs();
        Set<String> dbs = scmDbs.keySet();
        for(String db:dbs){
            if(sql.toLowerCase().contains(db)){
                sql=sql.replaceAll(db,scmDbs.get(db));
            }
            //将修改后的sql 更新至BoundSql对象中
            BoundSql boundSql = handler.getBoundSql();
            Field field = boundSql.getClass().getDeclaredField("sql");
            field.setAccessible(true);
            field.set(boundSql, sql);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
配置文件中注入Map对象
@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "scmGobalDb")
public class ScmGobalDbDefinition {
    private Map<String,String> scmDbs;

    public Map<String, String> getScmDbs() {
        return scmDbs;
    }

    public void setScmDbs(Map<String, String> scmDbs) {
        this.scmDbs = scmDbs;
    }
}
application.yml 配置
scmGobalDb:
      scmDbs:
       db1: ry_db1
       db2: ry_db2
       db3: ry_db3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值