在我看来,这个分页插件为mybatis量身定制。完美融合框架,一句多余的代码也不需要我们写.我们
MyBatis分页插件-PageHelper的配置与应用
一.引入PageHelper依赖
pom.xml 引入依赖:
<!-- pagehelper :分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<!-- pagehelper的依赖包:jsqlparser -->
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.5</version>
</dependency>
*如果不用maven需要自行下载两个jar包:
- http://repo1.maven.org/maven2/com/github/pagehelper/pagehelper/
- http://repo1.maven.org/maven2/com/github/jsqlparser/jsqlparser/0.9.5/
二.配置拦截器插件
spring-mybatis.xml 集成配置:
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:site/gaoyisheng/mapping/*.xml"></property>
<!-- 分页插件 pagehelper -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个 -->
<value>
helperDialect=postgresql
reasonable=true
supportMethodsArguments=true
params=count=countSql
autoRuntimeDialect=true
</value>
</property>
</bean>
</array>
</property>
</bean>
简单介绍其中参数,具体参数详见: 分页插件参数介绍
helperDialect:如果不配置,pagehelper会自动获取连接,检测数据库。也可以自己声明数据库的方言,比如此处用的postgresql。
reasonable:配置pageNum参数合理化,比如第0页,和超过最后一页,则返会第一页和最后一页。而不是意想不到的数据。
supportMethodsArguments:”支持通过 Mapper 接口参数来传递分页参数”,通过interface传给mapper.xml,默认false不支持.代码实例可见 例子:查询测试代码 , mapper.xml代码,查看详细的写法.展示了两种不同传值方法,
params=count=countSql 为了支持PageHelper.startPage(Object params)方法,默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero .
autoRuntimeDialect:运行时多数据源(数据库)自动识别,默认值false。true则允许自动识别对应方言的分页.
至此,我们已经配好一个简单可用的分页插件了.
三.使用分页插件
这里介绍其中一种方法,简单易懂.
1.mapper接口 简单易懂
最简单的使用方法是,通过mapper接口,传递分页参数:
/**
* .
* TODO 查看所有未认领的awards
* @param request
* @return
*/
@RequestMapping(value = "/notClaimed-list", method = RequestMethod.POST)
@ResponseBody
public Object notClaimedList(HttpServletRequest request) {
int pageNum = Integer.valueOf(request.getParameter("pageNum"));
int pageSize = Integer.valueOf(request.getParameter("pageSize"));
//注意,查询语句要紧跟下面这一条.
PageHelper.startPage(pageNum,pageSize);
List<ChPeriodicalThesis> ls = chPeriodicalThesisService.selectByStatus("未认领");
//返回PageInfo的JSON
return new PageInfo<ChPeriodicalThesis>(ls);
}
pageNum: 控制页数.
pageSize: 控制页面大小.
2.mapper.xml 框架已做好处理
在mapper.xml中,并不需要我们处理任何参数.{“pageNum”,”pageSize”} Mybatis框架会自动查找对应分页的数据然后返回.
<!-- 根据 认领状态 查询 -->
<select id="selectByStatus" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from en_periodical_thesis e
where e.claim_status = #{status}
</select>
不管你信不信,有了框架它就是这么方便.已经可以用了.我们再写个Service类和测试类跑跑看.
3. Service类 服务MV C
/**
* .
* TODO 通过认领状态查询,+分页参数:重载
* @param status
* @param pageNum
* @param pageSize
* @return
*/
public List<EnPeriodicalThesis> selectByStatus(String claimStatus) {
return thesisDao.selectByStatus(claimStatus);
}
3.JUnit 测试类
@Test
public void pageHelperTest() {
PageHelper.startPage(2,10);
List<ChPeriodicalThesis> ls = chService.selectAll();
PageInfo<ChPeriodicalThesis> pageInfo = new PageInfo<ChPeriodicalThesis>(ls);
System.out.println("当前页:" + pageInfo.getPageNum());
System.out.println("每页的数量:"+pageInfo.getPageSize());
System.out.println("当前页的数量:"+pageInfo.getSize());
//由于startRow和endRow不常用,这里说个具体的用法
//可以在页面中"显示startRow到endRow 共size条数据"
//当前页面第一个元素在数据库中的行号
//当前页面最后一个元素在数据库中的行号
System.out.println("显示"+pageInfo.getStartRow()+"到"+pageInfo.getEndRow() +"共"+pageInfo.getSize()+"条数据");
System.out.println("当前页面第一个元素在数据库中的行号: "+pageInfo.getStartRow());
System.out.println("当前页面最后一个元素在数据库中的行号: "+pageInfo.getEndRow());
System.out.println("总记录数: "+pageInfo.getTotal());
System.out.println("总页数: "+pageInfo.getPages());
System.out.println("前一页:"+pageInfo.getPrePage());
System.out.println("下一页:"+pageInfo.getNextPage());
System.out.println("是否为第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否为最后一页:"+pageInfo.isIsLastPage());
System.out.println("是否有前一页:"+pageInfo.isHasPreviousPage());
System.out.println("是否有下一页:"+pageInfo.isHasNextPage());
System.out.println("导航页码数:"+pageInfo.getNavigatePages());
System.out.println("所有导航页码数:");
for(int i : pageInfo.getNavigatepageNums()) {
System.out.println(" "+i+",");
}
}
查询结果:
- 查询状态”未认领”
- 第1页
- 每页2条数据
DEBUG - JDBC Connection [jdbc:postgresql://127.0.0.1:5432/trans, UserName=postgres, PostgreSQL JDBC Driver] will not be managed by Spring
DEBUG - ==> Preparing: SELECT count(0) FROM ch_periodical_thesis
DEBUG - ==> Parameters:
DEBUG - <== Total: 1
DEBUG - ==> Preparing: select id, key_id, provenance, year, ministry, period, name, key_words, all_auther_name, mechanism, claim_status from ch_periodical_thesis LIMIT ? OFFSET ?
DEBUG - ==> Parameters: 10(Integer), 10(Integer)
DEBUG - <== Total: 10
DEBUG - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7caa550]
DEBUG - Returning JDBC Connection to DataSource
当前页:2
每页的数量:10
当前页的数量:10
显示11到20共10条数据
当前页面第一个元素在数据库中的行号: 11
当前页面最后一个元素在数据库中的行号: 20
总记录数: 21582
总页数: 2159
前一页:1
下一页:3
是否为第一页:false
是否为最后一页:false
是否有前一页:true
是否有下一页:true
导航页码数:8
所有导航页码数:
1,
2,
3,
4,
5,
6,
7,
8,
总结:
好用,简单易上手.
参考资料:
https://pagehelper.github.io/docs/howtouse/#1-%E5%BC%95%E5%85%A5%E5%88%86%E9%A1%B5%E6%8F%92%E4%BB%B6
源码见:
个人项目源码路径:欢迎交流指教.
本文链接:欢迎交流指教.
参考封装PageInfo类
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2017 abel533@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.github.pagehelper;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
/**
* 对Page<E>结果进行包装
* <p/>
* 新增分页的多项属性,主要参考:http://bbs.youkuaiyun.com/topics/360010907
*
* @author liuzh/abel533/isea533
* @version 3.3.0
* @since 3.2.2
* 项目地址 : http://git.oschina.net/free/Mybatis_PageHelper
*/
@SuppressWarnings({"rawtypes", "unchecked"})
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;
public PageInfo() {
}
/**
* 包装Page对象
*
* @param list
*/
public PageInfo(List<T> list) {
this(list, 8);
}
/**
* 包装Page对象
*
* @param list page结果
* @param navigatePages 页码数量
*/
public PageInfo(List<T> list, int navigatePages) {
if (list instanceof Page) {
Page page = (Page) list;
this.pageNum = page.getPageNum();
this.pageSize = page.getPageSize();
this.pages = page.getPages();
this.list = page;
this.size = page.size();
this.total = page.getTotal();
//由于结果是>startRow的,所以实际的需要+1
if (this.size == 0) {
this.startRow = 0;
this.endRow = 0;
} else {
this.startRow = page.getStartRow() + 1;
//计算实际的endRow(最后一页的时候特殊)
this.endRow = this.startRow - 1 + this.size;
}
} else if (list instanceof Collection) {
this.pageNum = 1;
this.pageSize = list.size();
this.pages = this.pageSize > 0 ? 1 : 0;
this.list = list;
this.size = list.size();
this.total = list.size();
this.startRow = 0;
this.endRow = list.size() > 0 ? list.size() - 1 : 0;
}
if (list instanceof Collection) {
this.navigatePages = navigatePages;
//计算导航页
calcNavigatepageNums();
//计算前后页,第一页,最后一页
calcPage();
//判断页面边界
judgePageBoudary();
}
}
/**
* 计算导航页
*/
private void calcNavigatepageNums() {
//当总页数小于或等于导航页码数时
if (pages <= navigatePages) {
navigatepageNums = new int[pages];
for (int i = 0; i < pages; i++) {
navigatepageNums[i] = i + 1;
}
} else { //当总页数大于导航页码数时
navigatepageNums = new int[navigatePages];
int startNum = pageNum - navigatePages / 2;
int endNum = pageNum + navigatePages / 2;
if (startNum < 1) {
startNum = 1;
//(最前navigatePages页
for (int i = 0; i < navigatePages; i++) {
navigatepageNums[i] = startNum++;
}
} else if (endNum > pages) {
endNum = pages;
//最后navigatePages页
for (int i = navigatePages - 1; i >= 0; i--) {
navigatepageNums[i] = endNum--;
}
} else {
//所有中间页
for (int i = 0; i < navigatePages; i++) {
navigatepageNums[i] = startNum++;
}
}
}
}
/**
* 计算前后页,第一页,最后一页
*/
private void calcPage() {
if (navigatepageNums != null && navigatepageNums.length > 0) {
navigateFirstPage = navigatepageNums[0];
navigateLastPage = navigatepageNums[navigatepageNums.length - 1];
if (pageNum > 1) {
prePage = pageNum - 1;
}
if (pageNum < pages) {
nextPage = pageNum + 1;
}
}
}
/**
* 判定页面边界
*/
private void judgePageBoudary() {
isFirstPage = pageNum == 1;
isLastPage = pageNum == pages || pages == 0;;
hasPreviousPage = pageNum > 1;
hasNextPage = pageNum < pages;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getStartRow() {
return startRow;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public int getEndRow() {
return endRow;
}
public void setEndRow(int endRow) {
this.endRow = endRow;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
@Deprecated
// firstPage就是1, 此函数获取的是导航条上的第一页, 容易产生歧义
public int getFirstPage() {
return navigateFirstPage;
}
@Deprecated
public void setFirstPage(int firstPage) {
this.navigateFirstPage = firstPage;
}
public int getPrePage() {
return prePage;
}
public void setPrePage(int prePage) {
this.prePage = prePage;
}
public int getNextPage() {
return nextPage;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
@Deprecated
// 请用getPages()来获取最后一页, 此函数获取的是导航条上的最后一页, 容易产生歧义.
public int getLastPage() {
return navigateLastPage;
}
@Deprecated
public void setLastPage(int lastPage) {
this.navigateLastPage = lastPage;
}
public boolean isIsFirstPage() {
return isFirstPage;
}
public void setIsFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage;
}
public boolean isIsLastPage() {
return isLastPage;
}
public void setIsLastPage(boolean isLastPage) {
this.isLastPage = isLastPage;
}
public boolean isHasPreviousPage() {
return hasPreviousPage;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public boolean isHasNextPage() {
return hasNextPage;
}
public void setHasNextPage(boolean hasNextPage) {
this.hasNextPage = hasNextPage;
}
public int getNavigatePages() {
return navigatePages;
}
public void setNavigatePages(int navigatePages) {
this.navigatePages = navigatePages;
}
public int[] getNavigatepageNums() {
return navigatepageNums;
}
public void setNavigatepageNums(int[] navigatepageNums) {
this.navigatepageNums = navigatepageNums;
}
public int getNavigateFirstPage() {
return navigateFirstPage;
}
public int getNavigateLastPage() {
return navigateLastPage;
}
public void setNavigateFirstPage(int navigateFirstPage) {
this.navigateFirstPage = navigateFirstPage;
}
public void setNavigateLastPage(int navigateLastPage) {
this.navigateLastPage = navigateLastPage;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("PageInfo{");
sb.append("pageNum=").append(pageNum);
sb.append(", pageSize=").append(pageSize);
sb.append(", size=").append(size);
sb.append(", startRow=").append(startRow);
sb.append(", endRow=").append(endRow);
sb.append(", total=").append(total);
sb.append(", pages=").append(pages);
sb.append(", list=").append(list);
sb.append(", prePage=").append(prePage);
sb.append(", nextPage=").append(nextPage);
sb.append(", isFirstPage=").append(isFirstPage);
sb.append(", isLastPage=").append(isLastPage);
sb.append(", hasPreviousPage=").append(hasPreviousPage);
sb.append(", hasNextPage=").append(hasNextPage);
sb.append(", navigatePages=").append(navigatePages);
sb.append(", navigateFirstPage=").append(navigateFirstPage);
sb.append(", navigateLastPage=").append(navigateLastPage);
sb.append(", navigatepageNums=");
if (navigatepageNums == null) sb.append("null");
else {
sb.append('[');
for (int i = 0; i < navigatepageNums.length; ++i)
sb.append(i == 0 ? "" : ", ").append(navigatepageNums[i]);
sb.append(']');
}
sb.append('}');
return sb.toString();
}
}