分页的实现以及PageHelper的使用
在做项目时,分页属于很常见的小功能,但通常都会有很繁琐的封装,在这里介绍一款非常实用的插件— — — — — 分页插件pageHelper,能满足我们工作中的基本需求。
PageHelper介绍
PageHelper是国内的一款非常优秀的一款开源的mybatis插件,它支持基本主流与常用的数据库,例如mysql,oracle,DB2,SQLite,Hsqldb等
本项目在 github 的项目地址:https://github.com/pagehelper/Mybatis-PageHelper
PageHelper的使用
配置介绍
使用 Maven 在 pom.xml 中添加如下依赖
首先需要引入对应的依赖
<!--分页工具包-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
相关配置如下
特别注意,新版拦截器是 com.github.pagehelper.PageInterceptor 。 com.github.pagehelper.PageHelper 现 在是一个特殊的 dialect 实现类,是分页插件的默认实现类,提供了和以前相同的用法。
1.在 MyBatis 配置 xml 中配置拦截器插件
<plugins>
<!-- com.github.pagehelper为PageInterceptor类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="reasonable" value="true"/>
</plugin>
</plugins>`
2.在 Spring 配置文件中配置拦截器
上述配置也可以不配置在mybatis.xml中,也可以配置在spring-mybatis.xml的SqlSessionFactoryBean中,代码如下:
<!-- SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--分页插件配置-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<!--配置分页属性-->
<property name="properties">
<props>
<!--指定数据库方言-->
<prop key="helperDialect">mysql</prop>
<!--合理化分页操作-->
<prop key="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
相关参数介绍
helperDialect
分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect 属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
oracle , mysql , mariadb , sqlite , hsqldb , postgresql , db2 , sqlserver , informix , h2 , sqlserver201
rowBoundsWithCount
默认值为 false ,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置
为 true 时,使用 RowBounds 分页会进行 count 查询。
pageSizeZero
默认值为 false ,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.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
分页插件的使用
分页插件的使用很简单,配置好了后,直接调用PageHelper的静态方法startPage即可实现分页,其他查询正常写就行了,注意一点,调用startPage的方法必须写在执行查询selectAll()前面,否则分页无效。
/**
* 分页测试
*/
@Test
public void testPage(){
//page 当前页 size 每页显示多少条
int page = 1,size=10;
//分页处理,只需要调用PageHelper.startPage静态方法即可。
PageHelper.startPage(page,size);
//必须写在要真正执行的代码之前
//startPage的方法必须写在执行查询selectAll()前面
//查询
List<Brand> brands = brandMapper.selectAll();
//获取分页信息,注意这里传入了brands集合对象
PageInfo<Brand> pageInfo = new PageInfo<Brand>(brands);
System.out.println(pageInfo);
}
实例如下
aside.jsp
<li id="system-setting"><a
href="${pageContext.request.contextPath}/orders/findAll.do?page=1&size=4"> <i
class="fa fa-circle-o"></i> 订单管理
</a></li>
OrdersController.java contoller层
Controller
@RequestMapping("/orders")
public class OrdersController {
@Autowired
private IOrdersService ordersService;
//查询全部订单---未分页
// @RequestMapping("/findAll.do")
// public ModelAndView findAll() throws Exception {
// ModelAndView mv = new ModelAndView();
// List<Orders> ordersList = ordersService.findAll();
// mv.addObject("ordersList", ordersList);
// mv.setViewName("orders-list");
// return mv;
// }
@RequestMapping("/findAll.do")
//注意该默认的参数
public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") int page, @RequestParam(name = "size", required = true, defaultValue = "4") int size) throws Exception {
ModelAndView mv = new ModelAndView();
List<Orders> ordersList = ordersService.findAll(page, size);
//PageInfo就是一个分页Bean 重新封装
PageInfo pageInfo=new PageInfo(ordersList);
mv.addObject("pageInfo",pageInfo);
//通过modelAndview跳转到相关界面
mv.setViewName("orders-page-list");
return mv;
}
}
service层
@Service
@Transactional
public class OrdersServiceImpl implements IOrdersService {
@Autowired
private IOrdersDao ordersDao;
@Override
public List<Orders> findAll(int page, int size) throws Exception {
//参数pageNum 是页码值 参数pageSize 代表是每页显示条数
//必须写在要真正执行的代码之前
PageHelper.startPage(page, size);
return ordersDao.findAll();
}
}
数据返回显示的前台界面为:
orders-page-list.jsp 重点
<tbody>
<c:forEach items="${pageInfo.list}" var="orders">
<tr>
<td><input name="ids" type="checkbox"></td>
<td>${orders.id }</td>
<td>${orders.orderNum }</td>
<td>${orders.product.productName }</td>
<td>${orders.product.productPrice }</td>
<td>${orders.orderTimeStr }</td>
<td class="text-center">${orders.orderStatusStr }</td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs">订单</button>
<button type="button" class="btn bg-olive btn-xs" onclick="location.href='${pageContext.request.contextPath}/orders/findById.do?id=${orders.id}'">详情</button>
<button type="button" class="btn bg-olive btn-xs">编辑</button>
</td>
</tr>
</c:forEach>
</tbody>
```xml
重点注意PageInfo里已经给我们封装好了非常多的信息 例如总页数,总条数,当前页等等
重点注意此页码的编写
<div class="pull-left">
<div class="form-group form-inline">
总共2 页,共14 条数据。 每页
<!--注意onchange函数 选了某一个就会去调用相关函数-->
<select class="form-control" id="changePageSize" onchange="changePageSize()">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select> 条
</div>
</div>
<div class="box-tools pull-right">
<ul class="pagination">
<li>
<!--重点注意${pageInfo.pageSize}动态获取-->
<a href="${pageContext.request.contextPath}/orders/findAll.do?page=1&size=${pageInfo.pageSize}" aria-label="Previous">首页</a>
</li>
<li>
<!--重点注意pageInfo.pageNum 表示当前页-->
<a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum-1}&size=${pageInfo.pageSize}">上一页</a></li>
<c:forEach begin="1" end="${pageInfo.pages}" var="pageNum">
<li>
<!--用a标签-->
<a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageNum}&size=${pageInfo.pageSize}">${pageNum}
</a></li>
</c:forEach>
<!--重点注意pageInfo.pageNum 表示当前页-->
<li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum+1}&size=${pageInfo.pageSize}">下一页</a></li>
<li>
<a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pages}&size=${pageInfo.pageSize}" aria-label="Next">尾页</a>
</li>
</ul>
</div>
</div>
<!--重点注意此function方法-->
function changePageSize() {
//获取下拉框的值
//会根据id获取到相应的值
var pageSize = $("#changePageSize").val();
//向服务器发送请求,改变没页显示条数
location.href = "${pageContext.request.contextPath}/orders/findAll.do?page=1&size="
+ pageSize;
}