mybatis - 基于拦截器修改执行中的SQL语句

Posted cjunn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis - 基于拦截器修改执行中的SQL语句相关的知识,希望对你有一定的参考价值。

拦截器介绍

mybatis提供了@Intercepts注解允许开发者对mybatis的执行器Executor进行拦截。
Executor接口方法主要有update、query、commit、rollback等等。
主要思路为:

  1. 进入拦截器方法中
  2. 获取拦截器方法参数
  3. 获取解析参数及SQL
  4. 自定义生成自己的SQL语句
  5. 将自定义SQL设置进参数中
  6. 由mybatis处理后续问题

    拦截器代码

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Properties;
@Component
@Intercepts({@org.apache.ibatis.plugin.Signature(type = Executor.class, method = "query",
        args = {
        MappedStatement.class,
                Object.class,
                RowBounds.class,
                ResultHandler.class,
                CacheKey.class,
                BoundSql.class})})
public class MybatisInterceptorConfig implements Interceptor {
     /*自定义SQL*/
     private String resetSql(String sql) {
         
     }
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        resetSql(invocation);
        return invocation.proceed();
    }
    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o, this);
    }
    @Override
    public void setProperties(Properties properties) {
        
    }
    private void resetSql(Invocation invocation) {
        final Object[] args = invocation.getArgs();
        BoundSql boundSql = (BoundSql) args[5];
        if(StringUtils.isNotEmpty(boundSql.getSql())) {
            modify(boundSql,"sql",resetSql(boundSql.getSql()));
        }
    }
    private static void modify(Object object, String fieldName, Object newFieldValue){
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
            if(!field.isAccessible()) {
                field.setAccessible(true);
            }
            field.set(object, newFieldValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

以上是关于mybatis - 基于拦截器修改执行中的SQL语句的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis-Interceptor

Mybatis反射修改SQL值

Mybatis反射修改SQL值

MyBatis自定义Plugin

定义Mybatis拦截器动态切换postgre数据库schema

定义Mybatis拦截器动态切换postgre数据库schema