mybatis sql 改写

  • Post author:
  • Post category:其他


1mybatis sql 改写

package com.macro.mall.tiny.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


@Intercepts({
     @Signature(
             type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}
     )
})
@Slf4j
@Component
public class SqlRewriteInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
            StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
            MetaObject metaObject = MetaObject.forObject(statementHandler,
                    SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                    SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                    new DefaultReflectorFactory());

            //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement
            MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");

            //sql语句类型 select、delete、insert、update
            String sqlCommandType = mappedStatement.getSqlCommandType().toString();
            if (!"SELECT".equals(sqlCommandType)){
                //只是拦截:SELECT
                return invocation.proceed();
            }

            //id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser
            String id = mappedStatement.getId();
            log.info("拦截到当前请求方法的全路径名为--->:  " + id);

        //TODO 修改位置
        //注解逻辑判断  添加注解了才拦截
        Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf(".")));
        //获取接口方法名
        String methodName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length());
        boolean isPageCount = false;

        int j=0;

       
                //获取到原始sql语句
                BoundSql boundSql = statementHandler.getBoundSql();
                String sql = boundSql.getSql();

                //获取参数
                Object parameter = statementHandler.getParameterHandler().getParameterObject();
                log.info("拦截到当前请求SQL为--->: "  + sql);
                log.info("拦截到当前请求类型为--->: "  + sqlCommandType);
                log.info("拦截到当前请求参数为--->: "  + parameter);

          
                log.info("拦截到当前请求SQL改写之后为--->: "  + sql);
                sql=sql+" where 1=1";
                log.info("拦截后改写--->: "  + sql);
                //反射改写新的SQL
                Field field = boundSql.getClass().getDeclaredField("sql");
                field.setAccessible(true);
                field.set(boundSql, sql);
            
     


        // 执行完上面的任务后,不改变原有的sql执行过程
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {}
}



版权声明:本文为lucksczhd原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。