1. Mybatis分页插件 - PageHelper说明

如果你也在用Mybatis,建议尝试该分页插件,这个一定是最方便使用的分页插件。

该插件目前支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库分页。

点击提交BUG

2. 版本说明

2.1. 最新版本为3.4.2

PageInfo中的judgePageBoudary方法修改:

isLastPage = pageNum == pages && pageNum != 1;

//改为

isLastPage = pageNum == pages;

2.2. 版本3.4.1

· 重大bug修复,SqlParser解析sql失败的时候返回了不带count(*)的sql,导致查询失败。

· 产生原因,由于SqlParser在系统中出现的位置修改后,导致这里出现错误。

· 强烈推荐各位更新到最新版本。

2.3. 版本3.4.0

· 增加了对@SelectProvider注解方法的支持,不使用这种方式的不影响

· 对基本逻辑进行修改,减少反射调用和获取BoundSql次数

· 对支持的数据库全部通过完整测试

· 虽然变化大,但是影响范围小,不特殊通知各位了。

3. 使用方法

分页插件项目中的正式代码一共有个5个Java文件,这5个文件的说明如下:

· Page<E>[必须]:分页参数类,该类继承ArrayList,虽然分页查询返回的结果实际类型是Page<E>,但是可以完全不出现所有的代码中,可以直接当成List使用。返回值不建议使用Page,建议仍然用List。如果需要用到分页信息,使用下面的PageInfo类对List进行包装即可。

· PageHelper[必须]:分页插件拦截器类,对Mybatis的拦截在这个类中实现。

· PageInfo[可选]:Page<E>的包装类,包含了全面的分页属性信息。

· SqlParser[可选]:提供高效的count查询sql。主要是智能替换原sql语句为count(*),去除不带参数的order by语句。需要jsqlparser-0.9.1.jar支持。

· SqlUtil[必须]:分页插件工具类,分页插件逻辑类,分页插件的主要实现方法都在这个类中。

3.1. 引入分页插件

引入分页插件一共有下面3种方式,推荐使用引入分页代码的方式,这种方式易于控制,并且可以根据自己需求进行修改。

3.1.1. 引入分页代码

将本插件中的com.github.pagehelper包(点击进入gitosc包 | 点击进入github包)下面的三个类Page,PageHelper和SqlUtil放到项目中,如果需要使用PageInfo(强大的分页包装类),也可以放到项目中。如果想使用更高效的count查询,你也可以将SqlParser放到SqlUtil相同的包下,使用SqlParser时必须使用jsqlparser-0.9.1.jar。

3.1.2. 引入Jar包

如果你想使用本项目的jar包而不是直接引入类,你可以在这里下载各个版本的jar包(点击Download下的jar即可下载)

· https://oss.sonatype.org/content/repositories/releases/com/github/pagehelper/pagehelper/

· http://repo1.maven.org/maven2/com/github/pagehelper/pagehelper/

由于使用了sql解析工具,你还需要下载这个文件(这个文件完全独立,不依赖其他):

· SqlParser.jar:http://search.maven.org/remotecontent?filepath=com/github/jsqlparser/jsqlparser/0.9.1/jsqlparser-0.9.1.jar

· SqlParser - github地址:https://github.com/JSQLParser/JSqlParser

3.1.3. 使用maven

添加如下依赖:

  1. <dependency>
  2. <groupId>com.github.pagehelper</groupId>
  3. <artifactId>pagehelper</artifactId>
  4. <version>3.4.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.github.jsqlparser</groupId>
  8. <artifactId>jsqlparser</artifactId>
  9. <version>0.9.1</version>
  10. </dependency>

3.2. 在Mybatis配置xml中配置拦截器插件:

  1. <!--
  2.  
  3. plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
  4.  
  5. properties?, settings?,
  6.  
  7. typeAliases?, typeHandlers?,
  8.  
  9. objectFactory?,objectWrapperFactory?,
  10.  
  11. plugins?,
  12.  
  13. environments?, databaseIdProvider?, mappers?
  14.  
  15. -->
  16.  
  17. <plugins>
  18.  
  19. <!-- com.github.pagehelper为PageHelper类所在包名 -->
  20.  
  21. <plugin interceptor="com.github.pagehelper.PageHelper">
  22.  
  23. <property name="dialect" value="mysql"/>
  24.  
  25. <!-- 该参数默认为false -->
  26.  
  27. <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
  28.  
  29. <!-- 和startPage中的pageNum效果一样-->
  30.  
  31. <property name="offsetAsPageNum" value="true"/>
  32.  
  33. <!-- 该参数默认为false -->
  34.  
  35. <!-- 设置为true时,使用RowBounds分页会进行count查询 -->
  36.  
  37. <property name="rowBoundsWithCount" value="true"/>
  38.  
  39. <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
  40.  
  41. <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
  42.  
  43. <property name="pageSizeZero" value="true"/>
  44.  
  45. <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
  46.  
  47. <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
  48.  
  49. <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
  50.  
  51. <property name="reasonable" value="true"/>
  52.  
  53. </plugin>
  54.  
  55. </plugins>

这里的com.github.pagehelper.PageHelper使用完整的类路径。

其他五个参数说明:

1. 增加dialect属性,使用时必须指定该属性,可选值为oracle,mysql,mariadb,sqlite,hsqldb,postgresql,没有默认值,必须指定该属性

2. 增加offsetAsPageNum属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页时,会将offset参数当成pageNum使用,可以用页码和页面大小两个参数进行分页。

3. 增加rowBoundsWithCount属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页会进行count查询。

4. 增加pageSizeZero属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page类型)。

5. 增加reasonable属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。具体作用请看上面配置文件中的注释内容。

3.2.1. 如何选择配置这些参数

单独看每个参数的说明可能是一件让人不爽的事情,这里列举一些可能会用到某些参数的情况。

首先dialect属性是必须的,不需要解释。其他的参数一般情况下我们都不必去管,如果想了解何时使用合适,你可以参考以下场景:

3.2.1.1. 场景一

如果你仍然在用类似ibatis式的命名空间调用方式,你也许会用到rowBoundsWithCount,分页插件对RowBounds支持和Mybatis默认的方式是一致,默认情况下不会进行count查询,如果你想在分页查询时进行count查询,以及使用更强大的PageInfo类,你需要设置该参数为true。

3.2.1.2. 场景二

如果你仍然在用类似ibatis式的命名空间调用方式,你觉得RowBounds中的两个参数offset,limit不如pageNum,pageSize容易理解,你可以使用offsetAsPageNum参数,将该参数设置为true后,offset会当成pageNum使用,limit和pageSize含义相同。

3.2.1.3. 场景三

如果觉得某个地方使用分页后,你仍然想通过控制参数查询全部的结果,你可以配置pageSizeZero为true,配置后,如可以通过设置pageSize=0或者RowBounds.limit = 0就会查询出全部的结果。

3.2.1.4. 场景四

如果你分页插件使用于类似分页查看列表式的数据,如新闻列表,软件列表,你希望用户输入的页数不在合法范围(第一页到最后一页之外)时能够正确的响应到正确的结果页面,那么你可以配置reasonable为true,这时如果pageNum<1会查询第一页,如果pageNum>总页数会查询最后一页。

3.3. Spring配置方法

首先需要在Spring中配置org.mybatis.spring.SqlSessionFactoryBean。然后配置配置Mybatis的具体配置有两种方式,一种是用mybatis默认的xml配置,另一种就是完全使用spring的属性配置方式。

3.3.1. mybatis默认的xml配置

配置configLocation属性指向上面的mybatis-config.xml文件。有关分页插件的配置都在mybatis-config.xml,具体配置内容参考上面的mybatis-config.xml。

3.3.2. 使用spring的属性配置方式

使用spring的属性配置方式,可以使用plugins属性像下面这样配置:

  1. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  2.  
  3. <property name="dataSource" ref="dataSource"/>
  4.  
  5. <property name="mapperLocations">
  6.  
  7. <array>
  8.  
  9. <value>classpath:mapper/*.xml</value>
  10.  
  11. </array>
  12.  
  13. </property>
  14.  
  15. <property name="typeAliasesPackage" value="com.isea533.ssm.model"/>
  16.  
  17. <property name="plugins">
  18.  
  19. <array>
  20.  
  21. <bean class="com.github.pagehelper.PageHelper">
  22.  
  23. <property name="properties">
  24.  
  25. <value>
  26.  
  27. dialect=hsqldb
  28.  
  29. reasonable=true
  30.  
  31. </value>
  32.  
  33. </property>
  34.  
  35. </bean>
  36.  
  37. </array>
  38.  
  39. </property>
  40.  
  41. </bean>
  42.  
  43. 属性配置按照上面的方式配置,每个配置独立一行即可。

3.4. 如何在代码中使用

阅读前后请注意看重要提示

首先该分页插件支持以下两种调用方式:

//第一种,RowBounds方式的调用

List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));

//第二种,Mapper接口方式的调用,推荐这种使用方式。

PageHelper.startPage(1, 10);

List<Country> list = countryMapper.selectIf(1);

下面分别对这两种方式进行详细介绍

3.4.1. RowBounds方式的调用

List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));

使用这种调用方式时,你可以使用RowBounds参数进行分页,这种方式侵入性最小,我们可以看到,通过RowBounds方式调用只是使用了这个参数,并没有增加其他任何内容。

分页插件检测到使用了RowBounds参数时,就会对该查询进行物理分页

关于这种方式的调用,有两个特殊的参数是针对RowBounds的,你可以参看上面的场景一场景二

注:不只有命名空间方式可以用RowBounds,使用接口的时候也可以增加RowBounds参数,例如:

//这种情况下也会进行物理分页查询

List<Country> selectAll(RowBounds rowBounds);

3.4.2. PageHelper.startPage静态方法调用

在你需要进行分页的Mybatis方法前调用PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个Mybatis查询方法会被进行分页。

3.4.2.1. 例一:

  1. SqlSession sqlSession = MybatisHelper.getSqlSession();
  2.  
  3. CountryMapper countryMapper = sqlSession.getMapper(CountryMapper.class);
  4.  
  5. try {
  6.  
  7. //获取第1页,10条内容,默认查询总数count
  8.  
  9. PageHelper.startPage(1, 10);
  10.  
  11. //紧跟着的第一个select方法会被分页
  12.  
  13. List<Country> list = countryMapper.selectIf(1);
  14.  
  15. assertEquals(2, list.get(0).getId());
  16.  
  17. assertEquals(10, list.size());
  18.  
  19. //分页时,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,
  20.  
  21. //或者使用PageInfo类(下面的例子有介绍)
  22.  
  23. assertEquals(182, ((Page) list).getTotal());
  24.  
  25. } finally {
  26.  
  27. sqlSession.close();
  28.  
  29. }

3.4.2.2. 例二:

  1. SqlSession sqlSession = MybatisHelper.getSqlSession();
  2.  
  3. CountryMapper countryMapper = sqlSession.getMapper(CountryMapper.class);
  4.  
  5. try {
  6.  
  7. //获取第1页,10条内容,默认查询总数count
  8.  
  9. PageHelper.startPage(1, 10);
  10.  
  11. //紧跟着的第一个select方法会被分页
  12.  
  13. List<Country> list = countryMapper.selectIf(1);
  14.  
  15. //后面的不会被分页,除非再次调用PageHelper.startPage
  16.  
  17. List<Country> list2 = countryMapper.selectIf(null);
  18.  
  19. //list1
  20.  
  21. assertEquals(2, list.get(0).getId());
  22.  
  23. assertEquals(10, list.size());
  24.  
  25. //分页时,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,
  26.  
  27. //或者使用PageInfo类(下面的例子有介绍)
  28.  
  29. assertEquals(182, ((Page) list).getTotal());
  30.  
  31. //list2
  32.  
  33. assertEquals(1, list2.get(0).getId());
  34.  
  35. assertEquals(182, list2.size());
  36.  
  37. } finally {
  38.  
  39. sqlSession.close();
  40.  
  41. }

3.4.3. 例三,使用PageInfo的用法:

  1. //获取第1页,10条内容,默认查询总数count
  2.  
  3. PageHelper.startPage(1, 10);
  4.  
  5. List<Country> list = countryMapper.selectAll();
  6.  
  7. //用PageInfo对结果进行包装
  8.  
  9. PageInfo page = new PageInfo(list);
  10.  
  11. //测试PageInfo全部属性
  12.  
  13. //PageInfo包含了非常全面的分页属性
  14.  
  15. assertEquals(1, page.getPageNum());
  16.  
  17. assertEquals(10, page.getPageSize());
  18.  
  19. assertEquals(1, page.getStartRow());
  20.  
  21. assertEquals(10, page.getEndRow());
  22.  
  23. assertEquals(183, page.getTotal());
  24.  
  25. assertEquals(19, page.getPages());
  26.  
  27. assertEquals(1, page.getFirstPage());
  28.  
  29. assertEquals(8, page.getLastPage());
  30.  
  31. assertEquals(true, page.isFirstPage());
  32.  
  33. assertEquals(false, page.isLastPage());
  34.  
  35. assertEquals(false, page.isHasPreviousPage());
  36.  
  37. assertEquals(true, page.isHasNextPage());

本项目中包含大量测试,您可以通过查看测试代码了解使用方法。

测试代码地址:http://git.oschina.net/free/Mybatis_PageHelper/tree/master/src/test/java/com/github/pagehelper/test

4. 重要提示

4.1. PageHelper.startPage方法重要提示

只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select方法)方法会被分页。

4.2. 分页插件不支持带有for update语句的分页

对于带有for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。

4.3. 分页插件不支持关联结果查询

原因以及解决方法可以看这里:

http://my.oschina.net/flags/blog/274000

分支插件不支持关联结果查询,但是支持关联嵌套查询。只会对主sql进行分页,嵌套的sql不会被分页。

5. 相关链接

对应于oschub的项目地址:http://git.oschina.net/free/Mybatis_PageHelper

对应于github的项目地址:https://github.com/pagehelper/Mybatis-PageHelper

Mybatis-Sample(分页插件测试项目):http://git.oschina.net/free/Mybatis-Sample

Mybatis项目:https://github.com/mybatis/mybatis-3

Mybatis文档:http://mybatis.github.io/mybatis-3/zh/index.html

Mybatis专栏:

· Mybatis示例

· Mybatis问题集

更多下载参考:

Mybatis分页插件_PageHelper.rar

Mybatis学习---Mybatis分页插件 - PageHelper的更多相关文章

  1. 【MyBatis】MyBatis分页插件PageHelper的使用

    好多天没写博客了,因为最近在实习,大部分时间在熟悉实习相关的东西,也没有怎么学习新的东西,这周末学习了MyBatis的一个分页插件PageHelper,虽然没有那么的强大(我在最后会说明它的缺点),但 ...

  2. MyBatis学习总结_17_Mybatis分页插件PageHelper

    如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件. 分页插件支持任何复杂的单表.多表分页,部分特殊情况请看重要提示. 想要使用分页插件?请看如何使用分页插件. 物理分页 该 ...

  3. MyBatis学习总结(17)——Mybatis分页插件PageHelper

    如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件. 分页插件支持任何复杂的单表.多表分页,部分特殊情况请看重要提示. 想要使用分页插件?请看如何使用分页插件. 物理分页 该 ...

  4. MyBatis 分页插件PageHelper 后台报错

    今天遇到一个问题,使用MyBatis 分页插件PageHelper 进行排序分页后,能正常返回正确的结果,但后台却一直在报错 net.sf.jsqlparser.parser.ParseExcepti ...

  5. Mybatis的分页插件PageHelper

    Mybatis的分页插件PageHelper 项目地址:http://git.oschina.net/free/Mybatis_PageHelper  文档地址:http://git.oschina. ...

  6. mybatis分页插件PageHelper的使用(转)

    Mybatis 的分页插件PageHelper-4.1.1的使用 Mybatis 的分页插件 PageHelper 项目地址:http://git.oschina.net/free/Mybatis_P ...

  7. Mybatis分页插件PageHelper的配置和使用方法

     Mybatis分页插件PageHelper的配置和使用方法 前言 在web开发过程中涉及到表格时,例如dataTable,就会产生分页的需求,通常我们将分页方式分为两种:前端分页和后端分页. 前端分 ...

  8. Mybatis分页插件PageHelper使用

    一. Mybatis分页插件PageHelper使用  1.不使用插件如何分页: 使用mybatis实现: 1)接口: List<Student> selectStudent(Map< ...

  9. SpringBoot集成MyBatis的分页插件 PageHelper

    首先说说MyBatis框架的PageHelper插件吧,它是一个非常好用的分页插件,通常我们的项目中如果集成了MyBatis的话,几乎都会用到它,因为分页的业务逻辑说复杂也不复杂,但是有插件我们何乐而 ...

随机推荐

  1. 在Linux上使用C语言编程获取IPv4地址及子网掩码

    在Linux上(如Ubuntu或CentOS), 获取某个Network Interface比如eth0的IP地址等信息,我们可以使用ifconfig或者ip addr show命令. $ ifcon ...

  2. [中英对照]The Art Of Reporting Bugs | 报bug的艺术

    前言:因为最近要给兄弟Team分享一下如何有效地报告bug, 故多做一做功课.下面给出一篇博客的中英文对照翻译. The Art Of Reporting Bugs | 报bug的艺术 My init ...

  3. JS 开发者必须知道的十个 ES6 新特性

    这篇文章会给你简单介绍一下ES6.如果你还不知道什么是ES6的话,它是JavaScript一个新的实现,如果你是一个忙碌的JavaScript开发者(但谁不是呢),那么继续读下去吧,看看当今最热门的语 ...

  4. linux系统挂载U盘,中文文件名乱码解决方案

    本人(壮壮熊)所用系统:ubuntu 12.4 今天在使用mount指令挂在硬盘时,出现令人头疼的中文文件名乱码. 问题: 使用mount /dev/sdb1 /media指令挂在第二颗硬盘的第一个分 ...

  5. redis实战笔记(1)-第1章 初识Redis

    第1章 初识Redis 注:本书在redis3.0版本的,比如redis3.0以后支持服务端集群.3.0之前只能客户端分片.    本章主要内容 1.Redis与其他软件的相同之处和不同之处 2.Re ...

  6. 关于css浮动框是否脱离文档流的分析

    在了解浮动属性之前,首先我们先了解一下html中关于display属性的相关知识. display属性常用的有inline, block, inline-block. inline也就是内联的意思. ...

  7. Shell 编程-常见的文件处理命令

    touch 命令 touch命令用于创建空文件,例如有时应用程序希望在它们写入数据之前,某个日志文件就已经存在.这时可用touch命令创建一个空文件:touch test1:touch命令还可以用来改 ...

  8. javascript的ajax功能的概念和示例

    AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML). 个人理解:ajax就是无刷新提交,然后得到返回内容. 对应的不使用ajax时的传统网 ...

  9. 使用 IntelliJ IDEA 创建第一个java程序 Hello World

    1.首先打开新建项目窗口 1.1.选择创建java程序 1.2.Project SDK,选择jdk安装路径 1.3.Additional Libraries and Frameworks 额外的库与框 ...

  10. 撩课-Python-每天5道面试题-第3天

    一. 代码实现: 计算1到100之间, 所有的奇数之和 result = , ): result += i print(result) 二. 代码实现: 接收用户输入数字, 求出从0至这个数字的累加和 ...