Mybatis拦截器同时兼容mysql和oracle
近期,项目要求用的mybatis-plus框架需要同时兼容mysql和oracle,mysql和oracle数据库还是存在很大的差异的,如果是内置函数比如ifnull和nvl等的差异,只能采用在xml里用databaseId区分两个代码
但是如果要使用mybatis-plus里service层自带的那些增删改除方法,假设oracle数据库的表和字段都没有使用oracle关键字,那么自带的方法是完全可以兼容mysql和oracle的,但是如果oracle数据库的表使用了oracle关键字,那么在sql语句中必须加""来查找
举个例子 假设mysql和oracle表中都有user表 使用mysql: select * from user 是没问题的
但是在oracle中user这里建表的时候就得加"",而且是区分大小写的,因此使用oracle执行上面的语句是报错的
假设建表的时候user表时"User" 那么执行的sql语句应该是 select * from “User” 同理字段名也是一样的
因此,假设是oracle 在实体表中配置表名
这样子使用mybatis-plus的方法没问题,但是用mysql就会报错了,如果要使mysql可以运行,那么tablename得改为 @TableName(“user”)这种
因此基于这样的背景下,做了一个mybatis拦截器来拦截sql语句,如果是oracle数据库,则在关键词前后加""
@Component
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class,
RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class }),
@Signature(type = Executor.class, method = "update", args = {
MappedStatement.class, Object.class }),
@Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class,
RowBounds.class, ResultHandler.class }) })
public class KeywordInterceptor implements Interceptor {
// oracle关键字 将其转换为“大写”方式
private String oracleKeyWords = "user,mode";
// 这是sql语句的无关词
private String sqlChar = " ,()";
// 核心在这里转换sql
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
// 如果不是oracle 则不作处理
if (!"oracle".equals