插件源码进一步分析与pageHelper分页插件介绍

知识回顾

上一篇 自定义MyBatis插件。我们实习了自定义插件,接下来我们先分析一下他的执行逻辑。

Plugin 实现了 InvocationHandler 接口,因此它的 invoke 方法会拦截所有的方法调用。invoke 方法会 对所拦截的方法进行检测,以决定是否执行插件逻辑。

我们看看 org.apache.ibatis.plugin.Plugin.java

public class Plugin implements InvocationHandler {
    private final Object target;
    private final Interceptor interceptor;
    private final Map<Class<?>, Set<Method>> signatureMap;

    private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) {
        this.target = target;
        this.interceptor = interceptor;
        this.signatureMap = signatureMap;
    }

    public static Object wrap(Object target, Interceptor interceptor) {
        Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
        Class<?> type = target.getClass();
        Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
        return interfaces.length > 0 ? Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)) : target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            Set<Method> methods = (Set)this.signatureMap.get(method.getDeclaringClass());
            return methods != null && methods.contains(method) ? this.interceptor.intercept(new Invocation(this.target, method, args)) : method.invoke(this.target, args);
        } catch (Exception var5) {
            Exception e = var5;
            throw ExceptionUtil.unwrapThrowable(e);
        }
    }

	...
}

首先,invoke 方法会检测被拦截方法是否配置在插件的 @Signature 注解 中,若是,则执行插件逻辑,否则执行被拦截方法。插件逻辑封装在 org.apache.ibatis.plugin.Interceptor 的 intercept 方法中,该方法的参数类型为 Invocation ,主要用于存储目标类,方法以及方法参数列表。

public interface Interceptor {
    Object intercept(Invocation var1) throws Throwable;

    default Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    default void setProperties(Properties properties) {
    }
}

分页插件分享

MyBatis 可以使用第三方的插件来对功能进行扩展,分⻚助手 PageHelper 就是其中一个非常优秀的插件。它将分⻚的复杂操作进行封装,使用简单的方式即可获得带分⻚的数据。

开发步骤:

  1. 导入通用 PageHelper 的坐标

    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.3.1</version>
    </dependency>
    <dependency>
        <groupId>com.github.jsqlparser</groupId>
        <artifactId>jsqlparser</artifactId>
        <version>4.0</version>
    </dependency>
    
  2. 在 mybatis 核心配置文件中配置 PageHelper 插件并测试分⻚数据获取

    配置文件

    <!--注意:分⻚助手的插件 配置在通用馆mapper之前-->
    <plugin interceptor="com.github.pagehelper.PageHelper">
    <!—指定方言 —>
      <property name="dialect" value="mysql"/>
    </plugin>
    

测试:

   @Test
    public void testPageHelper() {
        //设置分⻚参数
        // PageHelper.startPage(1, 2);
        List<User> select = userMapper.findAll();
        for (User user : select) {
            System.out.println(user);
        }
    }

没有分页的结果

Total: 4
User{id=1, username='lisi'}
User{id=2, username='tom'}
User{id=8, username='测试2'}
User{id=9, username='测试3'}

分页的结果

Total: 2
User{id=1, username='lisi'}
User{id=2, username='tom'}

分页实例代码

mybatis-pager-demo

posted @ 2024-10-09 19:07  灯塔下的守望者  阅读(9)  评论(0编辑  收藏  举报