美文网首页
SpringBoot集成mybatis拦截器修改表名

SpringBoot集成mybatis拦截器修改表名

作者: code2roc | 来源:发表于2022-05-01 14:03 被阅读0次

    背景

    公司的框架是基于mysql5.7开发的,最近有一个应用项目部署在linux系统上,使用的是mysql8.0,安装时未开启大小写敏感忽略,客户又不允许重装mysql环境,导致一些框架代码和业务代码中表名使用大写的地方会出现表名找不不到的情况,所以需要进行统一处理

    自定义SQLAST适配器

    自定义ASTVisitorAdapter对表名进行修改

    public class MySqlExportTableAliasVisitor extends MySqlASTVisitorAdapter {
        @Override
        public boolean visit(SQLExprTableSource x) {
            SystemConfig systemConfig = SpringBootBeanUtil.getBean(SystemConfig.class);
            if(systemConfig.getDbTableNameProxy().equals("lowcase")){
                x.setExpr(x.getTableName().toLowerCase());
            }else if(systemConfig.getDbTableNameProxy().equals("upcase")){
                x.setExpr(x.getTableName().toUpperCase());
            }
            return true;
        }
    }
    

    自定义Mybatis拦截器

    通过BoundSql获取sql语句,使用Druid的SQLUtils对sql语句进行结构化分析,表名修改完成后再重新复制sql语句

    @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
    public class SQLTableNameHandleInterceptor implements Interceptor {
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            DataBaseInfoUtil dataBaseInfoUtil = SpringBootBeanUtil.getBean(DataBaseInfoUtil.class);
            if(dataBaseInfoUtil.checkOpenTableNameHandle()){
                StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
                MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, new DefaultObjectFactory(), new DefaultObjectWrapperFactory(), new DefaultReflectorFactory());
                BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
    
                String sql = boundSql.getSql();
                List<SQLStatement> stmtList  = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
                MySqlExportTableAliasVisitor visitor = new MySqlExportTableAliasVisitor();
                for (SQLStatement stmt : stmtList) {
                    stmt.accept(visitor);
                }
                String handleSQL = SQLUtils.toSQLString(stmtList, JdbcConstants.MYSQL);
    
                metaStatementHandler.setValue("delegate.boundSql.sql", handleSQL);
            }
            return invocation.proceed();
        }
    
        @Override
        public Object plugin(Object target) {
            return Plugin.wrap(target, this);
        }
    
        @Override
        public void setProperties(Properties properties) {
    
        }
    
    }
    

    注册自定义Myabits拦截器

    @Configuration
    public class FrameMyBatisPluginConfig {
        @Bean
        @Conditional({SQLTableNameHandleInterceptorCondition.class})
        public String SQLTableNameHandleInterceptor(SqlSessionFactory sqlSessionFactory) {
            //实例化插件
            SQLTableNameHandleInterceptor sqlTableNameHandleInterceptor = new SQLTableNameHandleInterceptor();
            //创建属性值
            Properties properties = new Properties();
            properties.setProperty("prop1","value1");
            //将属性值设置到插件中
            sqlTableNameHandleInterceptor.setProperties(properties);
            //将插件添加到SqlSessionFactory工厂
            sqlSessionFactory.getConfiguration().addInterceptor(sqlTableNameHandleInterceptor);
            return "interceptor";
        }
    }
    

    相关文章

      网友评论

          本文标题:SpringBoot集成mybatis拦截器修改表名

          本文链接:https://www.haomeiwen.com/subject/dzcpyrtx.html