在我的毕设项目中,我使用了PageHelper分页插件对数据进行了分页显示,下文是如何在Spring Boot中使用PageHelper分页插件。
pom配置
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!--Mybatis 分页插件 pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
application.properties配置
我这里使用了druid作为数据库连接池。
#druid
spring.datasource.druid.url=jdbc:mysql://localhost:3306/ciyou
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=123
# 初始化大小,最小,最大
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=20
# 配置获取连接等待超时的时间
spring.datasource.druid.max-wait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.time-between-eviction-runs-millis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.min-evictable-idle-time-millis=300000
#检测连接是否有效的sql
spring.datasource.druid.validation-query=SELECT 'x'
spring.datasource.druid.validation-query-timeout=60000
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
# PSCache Mysql下建议关闭
spring.datasource.druid.pool-prepared-statements=false
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=-1
#spring.datasource.druid.max-open-prepared-statements= #等价于上面的max-pool-prepared-statement-per-connection-size
#mybatis
#entity扫描的包名
mybatis.type-aliases-package=com.ciyou.edu.entity
#Mapper.xml所在的位置
mybatis.mapper-locations=classpath*:/mybaits/*Mapper.xml
#开启MyBatis的二级缓存
mybatis.configuration.cache-enabled=true
#pagehelper
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
在Service中使用PageHelper分页插件
接下来就可以使用PageHelper分页插件了。
PageHelper.startPage(pageNo, pageSize);这段代码表示,程序开始分页了,pageNo默认值是1,pageSize默认是10,意思是从第1页开始,每页显示10条记录
分页的包装类PageInfo
上面Service中return的是Page对象,需要把Page包装成PageInfo对象才能序列化。该插件也默认实现了一个PageInfo,但是默认实现的PageInfo不满足我们的需求,我们这里自己包装一个PageInfo。
package com.ciyou.edu.entity
import com.github.pagehelper.Page
/**
* 帮助分页的实体类
*/
class PageInfo<T> implements Serializable {
private static final long serialVersionUID = 1L
//当前页
private int pageNum
//每页的数量
private int pageSize
//总记录数
private long total
//总页数
private int pages
//结果集
private List<T> list
//是否为第一页
private boolean isFirstPage = false
//是否为最后一页
private boolean isLastPage = false
//导航页码数
private int navigatePages
//所有导航页号
private List<Integer> navigatepageNums
private String url //url的条件
public PageInfo() {
}
/**
* 包装Page对象
*
* @param list
*/
public PageInfo(List<T> list) {
if (list instanceof Page) {
Page page = (Page) list
this.pageNum = page.getPageNum()
this.pageSize = page.getPageSize()
this.pages = page.getPages()
this.list = page
this.total = page.getTotal()
} else if (list instanceof Collection) {
this.pageNum = 1
this.pageSize = list.size()
this.pages = 1
this.list = list
this.total = list.size()
}
if (list instanceof Collection) {
//判断页面边界
judgePageBoudary()
//计算导航条
getNavigatepage()
}
}
/**
* 判定页面边界
*/
void judgePageBoudary() {
isFirstPage = pageNum == 1
isLastPage = pageNum == pages
}
int getPageNum() {
return pageNum
}
void setPageNum(int pageNum) {
this.pageNum = pageNum
}
int getPageSize() {
return pageSize
}
void setPageSize(int pageSize) {
this.pageSize = pageSize
}
long getTotal() {
return total
}
void setTotal(long total) {
this.total = total
}
int getPages() {
return pages
}
void setPages(int pages) {
this.pages = pages
}
public List<T> getList() {
return list
}
void setList(List<T> list) {
this.list = list
}
boolean isIsFirstPage() {
return isFirstPage
}
void setIsFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage
}
boolean isIsLastPage() {
return isLastPage
}
void setIsLastPage(boolean isLastPage) {
this.isLastPage = isLastPage
}
boolean getIsFirstPage() {
return isFirstPage
}
boolean getIsLastPage() {
return isLastPage
}
int getNavigatePages() {
return navigatePages
}
void setNavigatePages(int navigatePages) {
this.navigatePages = navigatePages
}
List<Integer> getNavigatepageNums() {
return navigatepageNums
}
void setNavigatepageNums(List<Integer> navigatepageNums) {
this.navigatepageNums = navigatepageNums
}
String getUrl() {
return url
}
void setUrl(String url) {
this.url = url
}
/**
* 根据显示的导航页码数 计算得到导航条
* @param navigatePages 显示的导航页码数
* 默认为5个
*/
void getNavigatepage(int navigatePages = 5){
this.navigatePages = navigatePages
this.navigatepageNums = new ArrayList<Integer>()
//1.如果总页数<=navigatePages,那么页码列表为1 ~ totaPage 从第一页到总页数
if(this.pages <= navigatePages){
for(i in 1 .. this.pages){
this.navigatepageNums?.add(i)
}
}else{
//2.总页数>navigatePages的情况
//按公式计算,让列表的头为当前页-((navigatePages-1)/2);列表的尾为当前页+((navigatePages-1)/2)
int begin = this.pageNum - ((navigatePages - 1) / 2)
int end = this.pageNum + ((navigatePages - 1) / 2)
//处理begin出界
if(begin < 1){
//如果开头的导航码数小于1了,那么导航的码数就应该从1到navigatePages的情况
for(i in 1 .. navigatePages){
this.navigatepageNums?.add(i)
}
}else if(end > this.pages){
//处理end结尾的问题
//如果导航结尾超过总页码数,那么结尾应该为总页码数,开头应该为总页码数 - navigatePages
for(i in pages - navigatePages + 1 .. pages){
this.navigatepageNums?.add(i)
}
}else{
for(i in begin .. end){
this.navigatepageNums?.add(i)
}
}
}
}
@Override
public String toString() {
return "PageInfo{" +
"pageNum=" + pageNum +
", pageSize=" + pageSize +
", total=" + total +
", pages=" + pages +
", list=" + list +
", isFirstPage=" + isFirstPage +
", isLastPage=" + isLastPage +
", navigatePages=" + navigatePages +
", navigatepageNums=" + navigatepageNums +
", url='" + url + '\'' +
'}';
}
}
Controller返回PageInfo对象
@RequestMapping("/admin/manageStudent")
ModelAndView findStudentByPage(Integer page){
if(page == null){
page = 1
}
ModelAndView mv = new ModelAndView("admin/manageStudent")
logger.info("findStudentByPage : 查询第${page}页")
//不赋值pageSize,默认为10
Page<Student> students = studentService?.findByPage(page)
// 需要把Page包装成PageInfo对象才能序列化。该插件也默认实现了一个PageInfo
PageInfo<Student> pageInfo = new PageInfo<Student>(students)
logger.info("查询结果:" + pageInfo )
pageInfo?.setUrl("/admin/manageStudent?")
mv?.addObject("pageInfo",pageInfo)
return mv
}
Freemarker取得数据进行分页
<!-- /.box-body -->
<#if pageInfo?? && pageInfo.list?? && (pageInfo.list?size > 0) >
<div class="box-footer clearfix">
<ul class="pagination no-margin pull-right">
<li class="disabled"><a href="#">第${pageInfo.pageNum}页/共${pageInfo.pages}页</a></li>
<#if pageInfo.pageNum == 1>
<li class="disabled"><a>«</a></li>
<#else>
<li><a href="${pageInfo.url}page=${pageInfo.pageNum - 1}">«</a></li>
</#if>
<#list pageInfo.navigatepageNums as num>
<#if pageInfo.pageNum == num>
<li class="active"><a>${num}</a></li>
<#else>
<li><a href="${pageInfo.url}page=${num}">${num}</a></li>
</#if>
</#list>
<#if pageInfo.pageNum == pageInfo.pages>
<li class="disabled"><a>»</a></li>
<#else>
<li><a href="${pageInfo.url}page=${pageInfo.pageNum + 1}">»</a></li>
</#if>
</ul>
</div>
</#if>
最后就可以实现如下的分页效果了:
感谢如下资料提供的帮助:
Spring Boot+Mybatis+Pagehelper分页
关于Spring+mybatis+PageHelper分页插件PageHelper的使用策略