1. PageHelper介绍
PageHelper是国人开发的一款极其简单的数据库分页插件。只要在Java代码里添加一行简单的分页就可以实现简单的分页。参考官方github文档。
2. 示例代码
2.1 添加PageHelper的maven依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
2.2 配置分页插件,与Spring,Mybatis集成
<!-- 创建SqlSessionFactory,同时指定数据源 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
name="sqlSessionFactory">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:com/clickplus/mapper/business/*.xml" />
<property name="configLocation" value="classpath:mybatisMapper.xml"></property>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<!-- 这里的几个配置主要演示如何使用,如果不理解,一定要去掉下面的配置 -->
<property name="properties">
<value>
<!-- 分页插件会自动检测当前的数据库链接,自动选择合适的分页方式 -->
helperDialect=mysql
<!-- 分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页 -->
<!-- 希望用户输入的页数不在合法范围(第一页到最后一页之外)时能够正确的响应到正确的结果页面, 那么你可以配置 reasonable 为 true,这时如果 pageNum<=0 会查询第一页,如果 pageNum>总页数 会查询最后一页。 -->
reasonable=true
<!-- 如果你想在分页查询时进行 count 查询, 以及使用更强大的 PageInfo 类,你需要设置该参数为 true -->
<!-- 该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为true时,使用 RowBounds 分页会进行 count 查询。 -->
rowBoundsWithCount=true
<!-- 支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页 -->
supportMethodsArguments=true
<!-- 为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值 -->
<!-- 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero -->
params=count=countSql
<!-- 默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页 -->
autoRuntimeDialect=true
</value>
</property>
</bean>
</array>
</property>
</bean>
2.3 代码中使用分页
@Controller
@RequestMapping(value = "/test")
public class TestPageHelperController {
@Autowired
public InteriorAnalysisService interiorAnalysisService;
/**
* 在查询调用方法前声明分页信息(当前页,每页记录数)
*在查询调用方法对查询结果进行包装成PageInfo对象,也可以是定连续显示的页数,这也是常用功能。
*注意:都是与查询方法紧挨着的,不要中间夹杂其它无关语句
*
*/
@RequestMapping(value = "/getAutoBaseDayReportV4",method = RequestMethod.POST)
@ResponseBody
public Object getAutoBaseDayReportV4(@RequestParam(required = false,defaultValue = "1",value = "pn")Integer pn,
Map<String,Object> map){
//引入分页查询,使用PageHelper分页功能
//在查询之前传入当前页,然后多少记录
PageHelper.startPage(pn,5);
//startPage后紧跟的这个查询就是分页查询
List<AutoBaseDayReportV4> emps = interiorAnalysisService.getAll();
//使用PageInfo包装查询结果,只需要将pageInfo交给页面就可以
PageInfo pageInfo = new PageInfo<>(emps,5);
//pageINfo封装了分页的详细信息,也可以指定连续显示的页数
map.put("pageInfo",pageInfo);
return emps;
}
}
前端页面调用json接口,即可返回json格式的数据,前端如果传输的是{},则发现从数据返回了5个AutoBaseDayReportV4的json格式的数据。使用非常方便,对代码的侵入性小
3. PageHelper的方法使用
PageHelper的源码如下:
/**
* 获取任意查询方法的count总数
*
* @param select
* @return
*/
public static long count(ISelect select) {
Page<?> page = startPage(1, -1, true);
select.doSelect();
return page.getTotal();
}
/**
* 开始分页
*
* @param pageNum 页码
* @param pageSize 每页显示数量
*/
public static <E> Page<E> startPage(int pageNum, int pageSize) {
return startPage(pageNum, pageSize, true);
}
/**
* 开始分页
*
* @param pageNum 页码
* @param pageSize 每页显示数量
* @param count 是否进行count查询
*/
public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count) {
return startPage(pageNum, pageSize, count, null);
}
/**
* 开始分页
*
* @param pageNum 页码
* @param pageSize 每页显示数量
* @param orderBy 排序
*/
public static <E> Page<E> startPage(int pageNum, int pageSize, String orderBy) {
Page<E> page = startPage(pageNum, pageSize);
page.setOrderBy(orderBy);
return page;
}
/**
* 开始分页
*
* @param offset 页码
* @param limit 每页显示数量
*/
public static <E> Page<E> offsetPage(int offset, int limit) {
return offsetPage(offset, limit, true);
}
/**
* 开始分页
*
* @param offset 页码
* @param limit 每页显示数量
* @param count 是否进行count查询
*/
public static <E> Page<E> offsetPage(int offset, int limit, boolean count) {
Page<E> page = new Page<E>(new int[]{offset, limit}, count);
//当已经执行过orderBy的时候
Page<E> oldPage = SqlUtil.getLocalPage();
if (oldPage != null && oldPage.isOrderByOnly()) {
page.setOrderBy(oldPage.getOrderBy());
}
SqlUtil.setLocalPage(page);
return page;
}
/**
* 开始分页
*
* @param offset 页码
* @param limit 每页显示数量
* @param orderBy 排序
*/
public static <E> Page<E> offsetPage(int offset, int limit, String orderBy) {
Page<E> page = offsetPage(offset, limit);
page.setOrderBy(orderBy);
return page;
}
/**
* 开始分页
*
* @param pageNum 页码
* @param pageSize 每页显示数量
* @param count 是否进行count查询
* @param reasonable 分页合理化,null时用默认配置
*/
public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable) {
return startPage(pageNum, pageSize, count, reasonable, null);
}
/**
* 开始分页
*
* @param pageNum 页码
* @param pageSize 每页显示数量
* @param count 是否进行count查询
* @param reasonable 分页合理化,null时用默认配置
* @param pageSizeZero true且pageSize=0时返回全部结果,false时分页,null时用默认配置
*/
public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {
Page<E> page = new Page<E>(pageNum, pageSize, count);
page.setReasonable(reasonable);
page.setPageSizeZero(pageSizeZero);
//当已经执行过orderBy的时候
Page<E> oldPage = SqlUtil.getLocalPage();
if (oldPage != null && oldPage.isOrderByOnly()) {
page.setOrderBy(oldPage.getOrderBy());
}
SqlUtil.setLocalPage(page);
return page;
}
/**
* 开始分页
*
* @param params
*/
public static <E> Page<E> startPage(Object params) {
Page<E> page = SqlUtil.getPageFromObject(params);
//当已经执行过orderBy的时候
Page<E> oldPage = SqlUtil.getLocalPage();
if (oldPage != null && oldPage.isOrderByOnly()) {
page.setOrderBy(oldPage.getOrderBy());
}
SqlUtil.setLocalPage(page);
return page;
}
/**
* 排序
*
* @param orderBy
*/
public static void orderBy(String orderBy) {
Page<?> page = SqlUtil.getLocalPage();
if (page != null) {
page.setOrderBy(orderBy);
} else {
page = new Page();
page.setOrderBy(orderBy);
page.setOrderByOnly(true);
SqlUtil.setLocalPage(page);
}
}
/**
* 手动清空分页数据
*/
public static void clearPage(){
SqlUtil.clearLocalPage();
}
4. 注意事项以及错误原因
当时引入PageHelper是没注意我的Spring 版本是3.1 。去作者的github才发现配置是不同的。另外,对于mybatis的配置文件的配置项的顺序有一定要求,否则会报错,官方github地址请参考:PageHelper