SQL 拦截是一个比较有用的高级技巧,用户可以写一个 java 类,将传入 MyCat 的 SQL 进行改写然后交给 MyCat 去执行,此技巧可以完成如下一些特殊功能 :
1> 捕获和记录某些特殊的 SQL
2> 记录 SQL 查找异常
3> 出于性能优化的考虑,改写 SQL,比如改变查询条件的顺序或增加分页限制
4> 将某些 Select SQL 强制设置为 Read 模式,走读写分离 (很多事务框架很难剥离事务中的 Select SQL)
5> 后期 MyCat 智能优化,拦截所有 SQL 做智能分析,自动监控节点负载,自动优化路由,提供数据库优化建议
SQL 拦截的原理是在路由之前拦截 SQL,然后做其他处理,完成之后再做路由,执行,如下图所示 :
默认的拦截器实现 MySQL 转义字符的过滤转换,非默认拦截器只有一个拦截记录 SQL 的拦截器
1> 默认 SQL 拦截器
# 配置
<system>
<property name="sqlInterceptor">org.opencloudb.interceptor.impl.DefaultSqlInterceptor</property>
</system>
# 源码
/**
* escape mysql escape letter
*/
@Override
public String interceptSQL(String sql, int sqlType) {
if (sqlType == ServerParse.UPDATE || sqlType == ServerParse.INSERT||sqlType == ServerParse.SELECT||sqlType == ServerParse.DELETE) {
return sql.replace("\\'", "''");
} else {
return sql;
}
}
2> 捕获记录 SQL 拦截器配置
# 配置
<system>
<property name="sqlInterceptor">org.opencloudb.interceptor.impl.StatisticsSqlInterceptor</property>
<property name="sqlInterceptorType">select,update,insert,delete</property> <!-- 拦截 sql 类型 -->
<property name="sqlInterceptorFile">E:/mycat/sql.txt</property> <!-- sql 保存文件路径 -->
</system>
如果要实现自定义 SQL 拦截,只需要将配置类改为自己配置即可 :
1> 定义自定义类 implements SQLInterceptor ,然后改写 SQL 后返回
2> 将自己实现的类放入 catlet 目录,可以为 class 或 jar
3> 配置配置文件
<system>
<property name="sqlInterceptor">org.opencloudb.interceptor.impl.自定义 class</property>
<!-- 其他配置 -->
</system>