• SpringBoot集成mybatis拦截器修改表名


    背景

    公司的框架是基于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";
        }
    }
    
  • 相关阅读:
    WPF 获取本机所有字体拿到每个字符的宽度和高度
    WPF 自己封装 Skia 差量绘制控件
    WPF 漂亮的现代化控件 新 ModernWPF 界面库
    dotnet 在 UOS 国产系统上使用 MonoDevelop 创建 GTK 全平台带界面应用
    dotnet 在 UOS 国产系统上使用 MonoDevelop 进行拖控件开发 GTK 应用
    dotnet 在 UOS 国产系统上安装 MonoDevelop 开发工具
    通过java采集PC麦克风音频及播放wav音频文件
    nginx-http之ssl(九)
    nginx-http之proxy(八)
    nginx-http之upstream(七)
  • 原文地址:https://www.cnblogs.com/yanpeng19940119/p/16212770.html
Copyright © 2020-2023  润新知