Mybatis自定义插件Interceptor问题

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

Mybatis自定义插件Interceptor问题

什么时候怕过冷   2022-11-22 我要评论

Mybatis自定义插件-Interceptor

MyBatis允许你在映射语句执行过程中的某一点进行拦截调用。

默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

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

这些类中方法的细节可以通过查看每个方法的签名来发现,或者直接查看 MyBatis 发行包中的源代码。 如果你想做的不仅仅是监控方法的调用,那么你最好相当了解要重写的方法的行为。 因为在试图修改或重写已有方法的行为时,很可能会破坏 MyBatis 的核心模块。 这些都是更底层的类和方法,所以使用插件的时候要特别当心。

通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即.

@Intercepts(value = {@Signature(
        type = Executor.class,
        method = "query",
        args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class MyInterceptor implements Interceptor {
    //    @Autowired
    private Logger log = new LoggerStudoImpl();

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 该方法写入自己的逻辑
        Object[] queryArgs = invocation.getArgs();
        MappedStatement ms = (MappedStatement) queryArgs[0];
        BoundSql boundSql = ms.getBoundSql(queryArgs[1]);
        String sql = boundSql.getSql();
        String SQL = new StringBuilder(sql).append(" ").append("and deleted = '0'").toString();
        StaticSqlSource rawSqlSource = new StaticSqlSource(ms.getConfiguration(), SQL, boundSql.getParameterMappings());

        MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), rawSqlSource, ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.keyGenerator(ms.getKeyGenerator());
        if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) {
            builder.keyProperty(ms.getKeyProperties()[0]);
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(ms.getResultMaps());
        builder.resultSetType(ms.getResultSetType());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());
        MappedStatement statement = builder.build();
        queryArgs[0] = statement;
        log.error(SQL);
        return invocation.proceed();

    }

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

    @Override
    public void setProperties(Properties properties) {

    }
}

然后将自定义插件添加到Mybatis配置文件中,该插件就会生效。

   <plugins>
        <plugin interceptor="com.example.shiro.config.MyInterceptor"></plugin>
    </plugins>

自定义插件拦截的是Excutor中的query方法,也就是说只要是Mybatis执行查询,那么该插件就会拦截查询的SQL语句,将查询的SQL添加上and deleted = ‘0’,这样每次查询就无需加上deleted='0’了。

比如一些分页插件就是拦截的ReultSetHandle进而将查询的结果进行分页处理。

Mybatis Interceptor插件开发总结

Interviewceptor插件开发的demo先记录下,mybatis的加载过程和执行过程下次再补上

package com.syygl.test.study.mybatis;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.plugin.*;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

/**
 *type=
 * Executor          拦截执行器的方法
 * ParameterHandler  拦截参数的处理
 * ResultSetHandler  拦截结果集的处理
 * StatementHandler  拦截Sql语法构建的处理
 *
 * method的值是以上四个接口中的method
 *
 * args的值是method的参数
 *
 */


@Intercepts(
{
@Signature(type = Executor.class, method = "query", args = {})
}
)

public class InterceptorTest implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //Invocation是type中指定要拦截的对象   ---调用
        //proceed  ---继续
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        //是要拦截的对象才会进入处理方案
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}


/**
 * MybatisConfig用来将自定义的Interceptor添加进去
 */

@Configuration
class MybatisConfig {
    @Bean
    ConfigurationCustomizer mybatisConfigurationCustomizer() {
        return new ConfigurationCustomizer() {
            @Override
            public void customize(org.apache.ibatis.session.Configuration configuration) {
                configuration.addInterceptor(new InterceptorTest());
            }
        };
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们