【MyBatis】MyBatis分页插件PageHelper的使用
好多天没写博客了,因为最近在实习,大部分时间在熟悉实习相关的东西,也没有怎么学习新的东西,这周末学习了 MyBatis 的一个分页插件 PageHelper,虽然没有那么的强大(我在最后会说明它的缺点),但还是挺不错的。这篇博文主要来总结下如何使用 PageHelper。
我们知道,在MySQL中,分页的 sql 是使用 limit 来做,如果我们自己写 sql,那分页肯定是没有任何问题的。但是一旦 model 多了起来,复杂了起来,我们很自然的想到使用 mybatis 的逆向工程来生成相应的 po 和 mapper,但是同时也会带来弊端,比如这里的分页问题就不好解决了。
可能有人会说,我可以修改生成的文件,没错,这是可行的,但是一般我们通过逆向工程生成的文件,都不会去动它,所以这个时候,就需要使用分页插件来解决了。在介绍如何使用这个分页插件之前,先介绍一下 mybatis 中的插件是如何工作的,主要作用在哪个环节。我之前有写过一篇 mybatis 的一篇入门文章:宏观上把我 mybatis 框架。里面有张 mybatis 的工作原理图,为了方便叙述,我把图也放在这:
从图中可以看出,mybatis 中首先要在配置文件中配置一些东西,然后根据这些配置去创建一个会话工厂,再根据会话工厂创建会话,会话发出操作数据库的 sql 语句,然后通过执行器操作数据,再使用 mappedStatement 对数据进行封装,这就是整个 mybatis 框架的执行情况。那么 mybatis 的插件作用在哪一环节呢?它主要作用在 Executor 执行器与 mappedeStatement 之间,也就是说mybatis 可以在插件中获得要执行的 sql 语句,在 sql 语句中添加 limit 语句,然后再去对 sql 进行封装,从而可以实现分页处理。
搞清楚了分页插件的执行情况,下面来总结下 mybatis 中 PageHelper 的使用。
1. 需要引入 PageHelper 的 jar 包
如果没有使用 maven,那直接把 jar 包导入到 lib 文件夹下即可,这个 PageHelper 插件在 github 上有开源,地址为:https://github.com/pagehelper/Mybatis-PageHelper/tree/master/src/main/java/com/github/pagehelper。
如果使用了 maven,那么只要在 pom.xml 中引入该插件即可,引入如下:
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.4</version> </dependency>
2. 在 mybatis 的全局配置文件 SqlMapConfig.xml 中配置该插件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 配置分页插件 --> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库--> <property name="dialect" value="mysql"/> </plugin> </plugins></configuration>
3. 在执行 sql 前添加插件,完成分页功能
在查询的 sql 语句执行之前,添加一行代码PageHelper.startPage(1, 10);
第一个参数表示第几页,第二个参数表示每页显示的记录数。这样在执行 sql 后就会将记录按照语句中设置的那样进行分页。如果需要获取总记录数的话,需要 PageInfo 类的对象,这个对象可以获取总记录数,下面看下测试的代码。
public class TestPageHelper {@Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testPageHelper() { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个spring容器</span> ApplicationContext context = <span style="color: rgba(0, 0, 255, 1)">new</span> ClassPathXmlApplicationContext("classpath:spring/applicationContext-*"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 从spring容器中获取mapper代理对象</span> TbItemMapper mapper = context.getBean(TbItemMapper.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 执行查询并分页,TbItemExample是逆向工程自动生成的,用来进行条件查询,这里不设置则表示无条件</span> TbItemExample example = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> TbItemExample(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">分页处理,显示第一页的10条数据</span> PageHelper.startPage(1, 10<span style="color: rgba(0, 0, 0, 1)">); List</span><TbItem> list = mapper.selectByExample(example);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">查询 </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 取商品列表</span> <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">(TbItem item : list) { System.out.println(item.getTitle()); } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 取分页信息</span> PageInfo<TbItem> pageInfo = <span style="color: rgba(0, 0, 255, 1)">new</span> PageInfo<TbItem><span style="color: rgba(0, 0, 0, 1)">(list); </span><span style="color: rgba(0, 0, 255, 1)">long</span> total = pageInfo.getTotal(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取总记录数</span> System.out.println("共有商品信息:" +<span style="color: rgba(0, 0, 0, 1)"> total); }
}
看下执行的结果:
夏普(SHARP)LCD-46DS40A 46 英寸 日本原装液晶面板 智能全高清液晶电视
飞利浦 老人手机 (X2560) 深情蓝 移动联通 2G 手机 双卡双待
中兴 U288 珠光白 移动 3G 手机
三星 SCH-W899 亮金色 电信 3G 手机 双卡双待双通
飞利浦 老人手机 (X2560) 喜庆红 移动联通 2G 手机 双卡双待
飞利浦 老人手机 (X2560) 硬朗黑 移动联通 2G 手机 双卡双待
三星 Galaxy S4 (I9500)16G 版 皓月白 联通 3G 手机
三星 Galaxy S4 (I9500) 16G 版 星空黑 联通 3G 手机
三星 I8552 白色 联通 3G 手机 双卡双待
长虹(CHANGHONG) 3D51C1080i 51 英寸 快门式 3D 智能Android 电视(黑色)
共有商品信息:3096
可以看到,只显示出了 10 条数据,但是我总共有 3096 条数据,如果将参数改成 (2,10),那么就会显示第二页不同的 10 条数据,在这就不测试了。这说明 PageHelper 插件可以帮助我们实现分页功能,例如 EasyUI 中就会传到后台分页参数信息,后台就可以根据参数获取分页数据等等。
正如前面所说,这个 PageHelper 其实也有缺点,因为它对逆向工程生成的代码支持不好,不能对有查询条件的查询分页,会抛异常,上面是无条件查询的。当然,我们自己可以修改这个 PageHelper 插件,使其支持条件查询,当然,我是修改不了的……网上有修改过后的 PageHelper 插件,可以支持条件查询,相对来说就比较强大了,可以在自己的工程中依赖修改过后的分页插件进行开发。