MyBatis-Plus实现SQL执行前统一处理添加只读标识等注释

背景

由于项目中采用的DRDS数据库,为了实现查询语句在读库上执行,我们需要在sql前拼接/!TDDL:SALVE*/,对于以前的老项目,可以选择在代码里手动拼接的方式,但是对于我们采用了MyBatis-Plus插件的项目再采用xml中每个sql前拼接的方式,显得有那么一些些不和谐。因此我们可以利用MyBatis-Plus官方提供的能力,在sql执行前拦截,然后拼接我们想添加的任何注释内容

实现

首先我们需要引入MyBatis-Plus的pom文件,有版本限制,需要大于等于以下版本。

1、引入pon

xml 复制代码
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

2、自定义MyBatis的拦截器接口org.apache.ibatis.plugin.Interceptor

java 复制代码
@Slf4j
public class MyBatisPlusSqlAnnotationInterceptor implements InnerInterceptor {
	// 我们需要添加的注释
    private static final String READ_FLAG = "/!TDDL:SLAVE*/";

    // 添加环境变量控制注释是否启用
    private boolean readOnlyFlag;


    public MyBatisPlusSqlAnnotationInterceptor(boolean readOnlyFlag) {
        this.readOnlyFlag = readOnlyFlag;
    }

    @Override
    public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
            PluginUtils.MPStatementHandler handler = PluginUtils.mpStatementHandler(sh);
            MappedStatement ms = handler.mappedStatement();
            SqlCommandType sct = ms.getSqlCommandType();
            if (sct == SqlCommandType.SELECT && readOnlyFlag) {
                    BoundSql boundSql = handler.boundSql();
                    String sql = boundSql.getSql();
                    sql = READ_FLAG + sql;
                    try {
                        Field field = boundSql.getClass().getDeclaredField("sql");
                        field.setAccessible(true);
                        field.set(boundSql, sql);
                    } catch (NoSuchFieldException e) {
                        log.error("NoSuchFieldException:", e);
                    } catch (IllegalAccessException e) {
                        log.error("IllegalAccessException:", e);
                    }
                }
    }
}

3、配置MyBatis-Plus配置

java 复制代码
@Configuration
public class MybatisPlusConfig {
	// 配置文件控制执行与否
    @Value(value = "${flag.readOnly:true}")
    private boolean flagReadOnly;

    /**
     * 内置插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        // 增加我们的自定义插件
        interceptor.addInnerInterceptor(new MyBatisPlusSqlAnnotationInterceptor(flagReadOnly));
        return interceptor;
    }

    /**
     * Map下划线自动转驼峰
     */
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return i -> i.setObjectWrapperFactory(new MybatisMapWrapperFactory());
    }

}

参考

https://blog.csdn.net/weixin_42182797/article/details/130530899

相关推荐
XDHCOM1 天前
ORA-32484重复列名错误,ORACLE数据库CYCLE子句故障修复与远程处理方案
数据库·oracle
云烟成雨TD1 天前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
于慨1 天前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
swg3213211 天前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
翻斗包菜1 天前
PostgreSQL 日常维护完全指南:从基础操作到高级运维
运维·数据库·postgresql
gelald1 天前
SpringBoot - 自动配置原理
java·spring boot·后端
殷紫川1 天前
深入理解 AQS:从架构到实现,解锁 Java 并发编程的核心密钥
java
呆瑜nuage1 天前
MySQL表约束详解:8大核心约束实战指南
数据库·mysql
一轮弯弯的明月1 天前
贝尔数求集合划分方案总数
java·笔记·蓝桥杯·学习心得
chenjingming6661 天前
jmeter线程组设置以及串行和并行设置
java·开发语言·jmeter