Mybatis自定义SQL拦截器

本文介绍了如何在Mybatis中自定义SQL拦截器,深入理解Mybatis插件的基本原理,包括可以拦截的Executor、ParameterHandler、ResultSetHandler和StatementHandler等关键类的方法,并探讨了如何针对这些方法设置拦截点。同时,文中还提到了自定义注解的应用。
摘要由CSDN通过智能技术生成

自定义拦截器

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Properties;

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

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        StatementHandler statementHandler=(StatementHandler)invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");

        BoundSql boundSql = statementHandler.getBoundSql();
        //sql类型
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        //mapper方法的全路径名
        String id = mappedStatement.getId();

                //注解逻辑判断  添加注解了才拦截
        Class<?> classType = Class.forName(mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf(".")));
        String mName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length());
        for (Method method : classType.getDeclaredMethods()) {
            if (method.isAnnotationPresent(InterceptAnnotation.class) && mName.equals(method.getName())) {
                InterceptAnnotation interceptorAnnotation = method.getAnnotation(InterceptAnnotation.class);

                if (interceptorAnnotation.flag()) {
                    if(SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())){
                        String sql = boundSql.getSql();
                        String msql = sql.replace("where","where password = 'err' and ");
                        //通过反射拼接sql
                        Field field = boundSql.getClass().getDeclaredField("sql");
                        field.setAccessible(true);
                        field.set(boundSql, msql);
                    }
                }
            }
        }
        return invocation.proceed();
    }

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


    @Override
    public void setProperties(Properties properties) {

    }
}

Mybatis插件基本原理

Mybatis允许你在已经映射语句的执行过程中为某一点进行拦截调用。但是并不是对所有的方法都可以进行这种拦截处理,允许使用插件进行的拦截类如下,具体要拦截该类中哪一个方法则需要关注下mybatis的源码,去指定拦截时的方法入参:支持的拦截类如下:

  • Executor (update, query, flushStatements, commit, rollback, - getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface InterceptAnnotation {
    boolean flag() default true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值