MyBatis自定义插件通过实现Interceptor接口,结合@Intercepts和@Signature注解拦截Executor、ParameterHandler、ResultSetHandler、StatementHandler四大接口,在不修改源码的前提下,于SQL执行关键节点插入逻辑,实现功能扩展、性能监控等;需注意调用invocation.proceed()、避免性能开销、处理多插件顺序及线程安全,并确保外部操作与事务一致性。

MyBatis自定义插件的核心,在于它提供了一种非侵入式的能力,让你能在MyBatis执行SQL的生命周期中,插入自己的逻辑。简单来说,它就像在MyBatis内部流程的几个关键节点上安插了“哨兵”,这些“哨兵”可以在数据准备、SQL执行、结果处理等环节,读取、修改甚至替换掉原本的行为,而这一切都不需要你动MyBatis源码一根指头。这对于功能扩展、性能监控、日志记录或者数据权限控制来说,简直是神来之笔。
要编写一个MyBatis自定义插件,你主要需要实现MyBatis提供的
Interceptor
intercept
plugin
setProperties
Interceptor
@Intercepts
@Signature
@Intercepts
@Signature
type
Executor
ParameterHandler
ResultSetHandler
StatementHandler
method
args
intercept(Invocation invocation)
invocation
getTarget()
getMethod()
getArgs()
invocation.proceed()
plugin(Object target)
Plugin.wrap(target, this)
setProperties(Properties properties)
mybatis-config.xml
这是一个简单的示例,展示如何拦截
Executor
update
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.util.Properties;
@Intercepts({
    @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 PerformanceInterceptor implements Interceptor {
    private String authorName; // 演示如何获取配置属性
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            // 这是最关键的一步,放行,让MyBatis继续执行原有的方法
            Object result = invocation.proceed();
            return result;
        } finally {
            long end = System.currentTimeMillis();
            System.out.println("方法:" + invocation.getMethod().getName() + " 执行耗时:" + (end - start) + "ms. 作者: " + authorName);
            // 还可以获取更多信息,比如 invocation.getTarget() 得到被代理的Executor对象
            // 或者 invocation.getArgs() 得到方法的参数
        }
    }
    @Override
    public Object plugin(Object target) {
        // 返回一个代理对象,如果目标对象是Executor,就为其创建代理
        // 这样MyBatis在调用Executor的方法时,就会先经过这个拦截器
        return Plugin.wrap(target, this);
    }
    @Override
    public void setProperties(Properties properties) {
        // 在这里可以获取到MyBatis配置文件中为该插件设置的属性
        this.authorName = properties.getProperty("author");
        if (this.authorName == null) {
            this.authorName = "Unknown";
        }
        System.out.println("PerformanceInterceptor 初始化,获取到属性 author=" + authorName);
    }
}然后在
mybatis-config.xml
<configuration>
    <!-- ... 其他配置 ... -->
    <plugins>
        <plugin interceptor="your.package.PerformanceInterceptor">
            <property name="author" value="YourNameHere"/>
        </plugin>
    </plugins>
    <!-- ... 其他配置 ... -->
</configuration>MyBatis的插件机制,本质上是基于JDK动态代理实现的。它允许你拦截MyBatis内部的四个核心接口。理解这些接口各自的职责,是写好插件的前提。
Executor
Executor
Executor
MappedStatement
ParameterHandler
PreparedStatement
ParameterHandler
ResultSetHandler
ResultSet
ResultSetHandler
StatementHandler
Statement
StatementHandler
WHERE
通常情况下,我们最常打交道的是
Executor
StatementHandler
ParameterHandler
ResultSetHandler
写MyBatis插件,虽然功能强大,但确实有些地方稍不注意就会掉坑里。我个人就遇到过几次,挺让人抓狂的。
invocation.proceed()
intercept
invocation.proceed()
ClassCastException
invocation.getTarget()
args
intercept
mybatis-config.xml
plugin
target
MappedStatement
Executor
MappedStatement
MappedStatement
MappedStatement
MappedStatement
StatementHandler
MappedStatement
intercept
自定义MyBatis插件与事务管理协同工作,其实是一个比较自然的过程,因为插件本身就是MyBatis执行流程的一部分,它运行在MyBatis所管理的事务上下文之内。
事务边界内的操作:当你通过插件拦截
Executor
update
query
外部操作与事务:如果你的插件在
intercept
invocation.proceed()
Executor
Executor
SqlSession
Executor
Executor
SqlSession
Transaction
Transaction
intercept
总的来说,插件在MyBatis事务的“保护伞”下运行。大部分情况下,你不需要为插件的数据库操作单独考虑事务,它们会自然地融入当前会话的事务中。只有当你执行与MyBatis当前数据库连接无关的外部操作时,才需要特别注意事务边界和一致性问题。
以上就是mybatis 如何编写一个自定义插件?的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号