背景
由于项目中采用的DRDS数据库,为了实现查询语句在读库上执行,我们需要在sql前拼接/!TDDL:SALVE*/
,对于以前的老项目,可以选择在代码里手动拼接的方式,但是对于我们采用了MyBatis-Plus插件的项目再采用xml中每个sql前拼接的方式,显得有那么一些些不和谐。因此我们可以利用MyBatis-Plus官方提供的能力,在sql执行前拦截,然后拼接我们想添加的任何注释内容
实现
首先我们需要引入MyBatis-Plus的pom文件,有版本限制,需要大于等于以下版本。
1、引入pon
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
2、自定义MyBatis的拦截器接口org.apache.ibatis.plugin.Interceptor
@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配置
@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