5.13 mybatis之plugins使用

MyBatis插件的核心功能在于拦截和修改MyBatis框架在执行过程中的行为。具体来说,它可以拦截以下四大核心组件的方法调用:

  • Executor:执行器,负责SQL语句的执行和事务管理;
  • StatementHandler:语句处理器,处理具体的SQL语句,包括预编译和参数设置等;
  • ParameterHandler:参数处理器,负责将用户传递的参数转换成JDBC可识别的参数;
  • ResultSetHandler:结果集处理器,负责将JDBC返回的结果集转换成用户所需的对象或集合。

通过拦截这些方法调用,MyBatis插件可以实现诸如SQL重写、日志记录、性能监控、事务管理增强等多种功能。

mybatis的插件如何使用,我们通过插件实现统计SQL的耗时功能。

1. 首先实现Mybatis的Interceptor接口

package com.lzj.plugins;

import org.apache.ibatis.executor.Executor;
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.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.Properties;

@Intercepts(value = {
                @Signature(
                        type = Executor.class,	//type:标记需要拦截的类
                        method = "query", 		//method: 标记是拦截类的那个方法 	
                        args = { 				//args:标记拦截方法的入参
                                MappedStatement.class,
                                Object.class,
                                RowBounds.class,
                                ResultHandler.class
                        }
                )
        }
)
public class LogPlugin implements Interceptor {
    /*计算统计耗时的核心逻辑*/
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = invocation.proceed();
        System.out.println("耗时:" + (System.currentTimeMillis() - startTime));
        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Interceptor.super.plugin(target);
    }

	/*设置插件的属性*/
    @Override
    public void setProperties(Properties properties) {
        Interceptor.super.setProperties(properties);
    }
}

2. 实现耗时拦截器后还需要在mybatis配置文件中配置拦截器

 <plugins>
    <plugin interceptor="com.lzj.plugins.LogPlugin"></plugin>
</plugins>

只需执行完上述2步后,就可以正确打印出SQL的耗时了。
执行案例结果如下所示

Opening JDBC Connection
Created connection 868815265.
==>  Preparing: select * from car where name=? 
==> Parameters: xiaoli(String)
<==    Columns: name, brand
<==        Row: xiaoli, BYD
<==      Total: 1
耗时:154

另外Interceptor接口中还一个setProperties方法,那么该方法是起什么作用呢?其实该方法起到了向拦截器传递参数的作用。那么具体如何使用呢,还是以上面的例子,执行结果耗时打印出来是154,但是不知道是耗时154ms还是154s,比较模糊,假设这个单位我们支持通过参数传递。那么首先配置文件修改成如下所示,其中property指定了向拦截器传递一个name为MyPlugin,value为ms的参数

<plugins>
    <plugin interceptor="com.lzj.plugins.LogPlugin" >
        <property name="MyPlugin" value="ms"/>
    </plugin>
</plugins>

然后自定义的LogPlugin拦截器类修改如下所示

package com.lzj.plugins;

import org.apache.ibatis.executor.Executor;
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.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.util.Properties;

@Intercepts(value = {
                @Signature(
                        type = Executor.class,
                        method = "query",
                        args = {
                                MappedStatement.class,
                                Object.class,
                                RowBounds.class,
                                ResultHandler.class
                        }
                )
        }
)
public class LogPlugin implements Interceptor {

    private Properties properties;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = invocation.proceed();
        System.out.println("耗时:" + (System.currentTimeMillis() - startTime) + properties.getProperty("MyPlugin"));
        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Interceptor.super.plugin(target);
    }

    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

再次执行结果打印的耗时就带单位了,如下所示

Opening JDBC Connection
Created connection 868815265.
==>  Preparing: select * from car where name=? 
==> Parameters: xiaoli(String)
<==    Columns: name, brand
<==        Row: xiaoli, BYD
<==      Total: 1
耗时:146ms
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值