目录
使用pageHelper的步骤
一 引入分页插件
二 配置拦截器插件
分页插件的可选参数介绍:
三 分页插件在代码中的使用
分页插件的执行原理:
在实际应用中查询分页代码
pageHelper的安全调用:
PageInfo对象介绍
pageHelper是国内非常优秀的一款mybatis分页插件,支持基本的主流与常用的数据库.
使用pageHelper的步骤
一 引入分页插件
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>最新版本</version>
</dependency>
二 配置拦截器插件
在dao层的applicationContext-dao.xml配置文件中,配置以下内容
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="cn.itcast.domain"/>
<!--配置spring和mybatis整合分页插件-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面方式配置参数,一行配置一个,可以不用配置可使用默认值-->
<value>
helperDialect=mysql
</value>
</property>
</bean>
</array>
</property>
</bean>
分页插件的可选参数介绍:
- 默认情况下,我们会使用PageHelper的方式进行分页,pageHelper实现了dialect接口,,如果想要实现自己的分页逻辑,也可以通过实现Dialect接口(com.github.pagehelper.Dialect),然后配置该属性为实现类的全限定名称.

- 在默认dialect情况下,有以下几个参数可以进行设置,但是在实际的应用过程中可以省略配置,使用默认值即可.
-
helperDialect:自动检测当前数据库的连接,选择合适的分页方式.也可以配置此属性指定使用哪种数据库连接的分页方式(oracle mysql db2 .....等)
- 注意:使用SqlServer2012数据库时,需要手动指定为sqlserver2012,否则会使用SqlServer2015的方式进行分页
-
offsetAsPageNum:默认值为false,对使用RowsBounds作为分页参数有效,当参数为true时,会将RowBounds中的offset参数当成pageNum使用,可以用页码和页面大小两个参数进行分页.
- rowBoundsWithCount:默认值为false,对使用RowBounds作为分页参数时有效,当该参数设置为true时,使用RowBounds分页会进行count查询
- pageSizeZero: 默认值为false,当该参数设置为true时,如果pageSize=0或者RowsBounds.limit=0就会查询出全部的结果(相当于没有执行分页查询,但是返回的结果仍然是page类型)
- reasonable:分页合理化参数,默认值为false,当该参数为true时,pageNum<=0时查询第一页,pageNum>pages(超过总数时),会查询最后一页,默认为false,直接根据参数进行查询
- params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值,可以配置pageNum, pageSize, count, pageSizeZero, reasonable ,不配置映射则使用默认值,默认值为:pageNum=pageNum, pageSize=pageSize, count=countSql,reasonable=reasonable; pageSizeZero=pageSizeZero
- supportMethodArguments:支持通过Mapper接口参数来传递分页参数,默认值为false,分页插件从查询方法的参数中,自动根据上面params配置的字段中取值,查找到合适的值就会自动进行分页.
- autoRuntimeDialect:默认值为false.设置为true时,允许在运行时根据多数据源自动识别对应的方言进行分页(不支持自动选择SqlServer2012).
-
closeConn:默认值为true当使用运行时动态数据源或者设置helperDialect属性自动获取数据库类型是,会自动获取一个数据库连接,通过该属性来设置是否关闭获取这个连接,默认true关闭,设置为false后,不会关闭获取的连接,参数的设置根据自己选择的数据源来决定
参数的使用场景和参考连接:https://pagehelper.github.io/docs/howtouse/
三 分页插件在代码中的使用
分页插件的调用有多种方式,最用的有以下两种调用方式.
- //第二种,Mapper接口方式的调用,pagehelper的startPage方法。
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
- //第三种,Mapper接口方式的调用,pagehelper的offsetPage方法。
PageHelper.offsetPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
分页插件的执行原理:

mybatis执行SQL语句的时候,会首先在sqlsessionFactory工厂中创建sqlsession对象,然后sqlsession进入Executor执行器中执行方法,在执行方法之前,mybatis拦截器对方法进行了拦截,判断是否包含select查询语句,如果包含了select查询语句,则给语句后面拼接上limit条件语句,然后将拼接后的语句返回给执行器去执行,最后去数据库中查询结果然后返回
在实际应用中查询分页代码写在service模块中,代码样式如下:
service:
// PageInfo等同于我们自定义的pageBean 并且比pageBean更完善
public PageInfo<Company> findByPage(Integer page, Integer pageSize) {
PageHelper.startPage(page,pageSize); //使用分页插件 一定要紧跟一个查询方法
List<Company> list = companyDao.findAll(); //表面上是查询所有,但是执行时已经分页了
return new PageInfo<Company>(list,5);
}
controller:
@RequestMapping(value = "/list", name = "查询用户信息")
@RequestParam(defalutValue):属性值代表默认值
public String findAdd(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "5") Integer pageSize) {
//根据分页查询用户信息
PageInfo<User> pageInfo = userService.findByPage(getCompanyId(), page, pageSize);
//将pageInfo信息保存到request域中
request.setAttribute("page", pageInfo);
//重定向
return "system/user/user-list";
}
pageHelper的安全调用:
pageHelper在使用startPage方法的时候,后面必须跟随一个查询的方法,因为pageHelper使用了静态的ThreadLocal参数,分页参数和线程是绑定的,而在finally代码中自动清除了ThreadLocal存储的对象.如果代码在进入Executor前发生异常,就会导致线程不可用,同时也不会导致ThreadLocal参数被 错误的使用

PageInfo对象介绍
public class PageInfo<T> implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//由于startRow和endRow不常用,这里说个具体的用法
//可以在页面中"显示startRow到endRow 共size条数据"
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
//是否有前一页
private boolean hasPreviousPage = false;
//是否有下一页
private boolean hasNextPage = false;
//导航页码数
private int navigatePages;
//所有导航页号
private int[] navigatepageNums;
//导航条上的第一页
private int navigateFirstPage;
//导航条上的最后一页
private int navigateLastPage;
}