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

相关推荐
cike_y1 天前
Mybatis之解析配置优化
java·开发语言·tomcat·mybatis·安全开发
云老大TG:@yunlaoda3601 天前
华为云国际站代理商TaurusDB的成本优化体现在哪些方面?
大数据·网络·数据库·华为云
TG:@yunlaoda360 云老大1 天前
华为云国际站代理商GeminiDB的企业级高可用具体是如何实现的?
服务器·网络·数据库·华为云
是一个Bug1 天前
Java基础50道经典面试题(四)
java·windows·python
Slow菜鸟1 天前
Java基础架构设计(三)| 通用响应与异常处理(分布式应用通用方案)
java·开发语言
我是Superman丶1 天前
《Spring WebFlux 实战:基于 SSE 实现多类型事件流(支持聊天消息、元数据与控制指令混合传输)》
java
廋到被风吹走1 天前
【Spring】常用注解分类整理
java·后端·spring
是一个Bug1 天前
Java基础20道经典面试题(二)
java·开发语言
Z_Easen1 天前
Spring 之元编程
java·开发语言
leoufung1 天前
LeetCode 373. Find K Pairs with Smallest Sums:从暴力到堆优化的完整思路与踩坑
java·算法·leetcode