远方的灯塔 - 专注于服务端技术分享 远方的灯塔 - 专注于服务端技术分享
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 《C程序设计语言》
心情随笔
  • 文章分类
  • 文章标签
  • 文章归档
友情链接
关于我
GitHub (opens new window)

Terwer Green

一个后端老菜鸟
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 《C程序设计语言》
心情随笔
  • 文章分类
  • 文章标签
  • 文章归档
友情链接
关于我
GitHub (opens new window)
  • MyBatis

    • 解析原生JDBC开发问题与优化方案
    • 自定义持久层框架的设计思路
    • 自定义持久层框架的代码实现一
    • 自定义持久层框架的代码实现二
    • 使用getMapper方式对自定义持久层框架进行优化
    • MyBatis的基本介绍及优势
    • MyBatis的基本使用
    • Mybatis基本流程及配置文件解析
    • MyBatis复杂映射开发之一对一查询
    • MyBatis复杂映射开发之一对多查询
    • MyBatis复杂映射开发之多对多查询
    • MyBatis常用注解及基本增删改查的注解实现
    • MyBatis的注解实现复杂映射开发
    • MyBatis缓存的概念
    • 深度剖析MyBatis的一级缓存
    • 深度剖析MyBatis的二级缓存
    • MyBatis的二级缓存整合redis
    • MyBatis-RedisCache源码分析
    • MyBatis机制介绍与原理
    • 自定义MyBatis插件
    • 插件源码进一步分析与pageHelper分页插件介绍
      • 知识回顾
      • 分页插件分享
    • 通用 Mapper 封装
    • 深入剖析MyBatis的架构原理
  • 《设计模式》

  • 后端开发
  • MyBatis
terwer
2024-10-09
目录

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

本文介绍了 MyBatis 分页插件 PageHelper,通过导入依赖并配置插件,可以实现简单获取带分页的数据。通过配置插件和测试代码示例展示了如何使用 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);
        }
    }

	...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

首先,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) {
    }
}
1
2
3
4
5
6
7
8
9
10

# 分页插件分享

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>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  2. 在 mybatis 核心配置文件中配置 PageHelper 插件并测试分⻚数据获取

    配置文件

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

测试:

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

没有分页的结果

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

分页的结果

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

分页实例代码

mybatis-pager-demo (opens new window)

编辑 (opens new window)
上次更新: 2024/10/09, 11:04:25
自定义MyBatis插件
通用 Mapper 封装

← 自定义MyBatis插件 通用 Mapper 封装→

最近更新
01
深入剖析MyBatis的架构原理
12-04
02
通用 Mapper 封装
10-09
03
判定字符是否唯一
06-13
更多文章>
Theme by Vdoing | Copyright © 2011-2024 Terwer Green | MIT License | 粤ICP备2022020721号-1 | 百度统计
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式