综合概述
想必大家都有过这样的体验,在使用Mybatis时,最头痛的就是写分页了,需要先写一个查询count的select语句,然后再写一个真正分页查询的语句,当查询条件多了之后,会发现真的不想花双倍的时间写 count 和 select,幸好我们有 pagehelper 分页插件,pagehelper 是一个强大实用的 MyBatis 分页插件,可以帮助我们快速的实现MyBatis分页功能,而且pagehelper有个优点是,分页和Mapper.xml完全解耦,并以插件的形式实现,对Mybatis执行的流程进行了强化,这有效的避免了我们需要直接写分页SQL语句来实现分页功能。那么,接下来我们就来一起体验下吧。
实现案例
接下来,我们就通过实际案例来讲解如何使用pagehelper来实现MyBatis分页,为了避免重复篇幅,此篇教程的源码基于《Spring Boot:整合MyBatis框架》一篇的源码实现,读者请先参考并根据教程链接先行获取基础源码和数据库内容。
添加相关依赖
首先,我们需要在 pom.xml 文件中添加分页插件依赖包。
pom.xml
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.5
添加相关配置
然后在 application.yml 配置文件中添加分页插件有关的配置。
application.yml
# pagehelper
pagehelper:
helperDialect: mysql
reasonable:truesupportMethodsArguments:trueparams: count=countSql
编写分页代码
首先,在 DAO 层添加一个分页查找方法。这个查询方法跟查询全部数据的方法除了名称几乎一样。
SysUserMapper.java
packagecom.louis.springboot.demo.dao;importjava.util.List;importcom.louis.springboot.demo.model.SysUser;public interfaceSysUserMapper {intdeleteByPrimaryKey(Long id);intinsert(SysUser record);intinsertSelective(SysUser record);
SysUser selectByPrimaryKey(Long id);intupdateByPrimaryKeySelective(SysUser record);intupdateByPrimaryKey(SysUser record);/*** 查询全部用户
*@return
*/ListselectAll();/*** 分页查询用户
*@return
*/ListselectPage();
}
然后在 SysUserMapper.xml 中加入selectPage的实现,当然你也可以直接用@Select注解将查询语句直接写在DAO代码,但我们这里选择写在XML映射文件,这是一个普通的查找全部记录的查询语句,并不需要写分页SQL,分页插件会拦截查询请求,并读取前台传来的分页查询参数重新生成分页查询语句。
SysUserMapper.xml
selectfrom sys_user
服务层通过调用DAO层代码完成分页查询,这里统一封装分页查询的请求和结果类,从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会影响服务层以上的分页接口,起到了解耦的作用。
SysUserService.java
packagecom.louis.springboot.demo.service;importjava.util.List;importcom.louis.springboot.demo.model.SysUser;importcom.louis.springboot.demo.util.PageRequest;importcom.louis.springboot.demo.util.PageResult;public interfaceSysUserService {/*** 根据用户ID查找用户
*@paramuserId
*@return
*/SysUser findByUserId(Long userId);/*** 查找所有用户
*@return
*/ListfindAll();/*** 分页查询接口
* 这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象, 如MyBatis或JPA的分页对象
* 从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会
* 影响服务层以上的分页接口,起到了解耦的作用
*@parampageRequest 自定义,统一分页查询请求
*@returnPageResult 自定义,统一分页查询结果*/PageResult findPage(PageRequest pageRequest);
}
服务实现类通过调用分页插件完成最终的分页查询,关键代码是 PageHelper.startPage(pageNum, pageSize),将前台分页查询参数传入并拦截MyBtis执行实现分页效果。
SysUserServiceImpl.java
packagecom.louis.springboot.demo.service.impl;importjava.util.List;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importcom.github.pagehelper.PageHelper;importcom.github.pagehelper.PageInfo;importcom.louis.springboot.demo.dao.SysUserMapper;importcom.louis.springboot.demo.model.SysUser;importcom.louis.springboot.demo.service.SysUserService;importcom.louis.springboot.demo.util.PageRequest;importcom.louis.springboot.demo.util.PageResult;importcom.louis.springboot.demo.util.PageUtils;
@Servicepublic class SysUserServiceImpl implementsSysUserService {
@AutowiredprivateSysUserMapper sysUserMapper;
@OverridepublicSysUser findByUserId(Long userId) {returnsysUserMapper.selectByPrimaryKey(userId);
}
@Overridepublic ListfindAll() {returnsysUserMapper.selectAll();
}
@OverridepublicPageResult findPage(PageRequest pageRequest) {returnPageUtils.getPageResult(pageRequest, getPageInfo(pageRequest));
}/*** 调用分页插件完成分页
*@parampageQuery
*@return
*/
private PageInfogetPageInfo(PageRequest pageRequest) {int pageNum =pageRequest.getPageNum();int pageSize =pageRequest.getPageSize();
PageHelper.startPage(pageNum, pageSize);
List sysMenus =sysUserMapper.selectPage();return new PageInfo(sysMenus);
}
}
在控制器SysUserController中添加分页查询方法,并调用服务层的分页查询方法。
SysUserController.java
packagecom.louis.springboot.demo.controller;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importcom.louis.springboot.demo.service.SysUserService;importcom.louis.springboot.demo.util.PageRequest;
@RestController
@RequestMapping("user")public classSysUserController {
@AutowiredprivateSysUserService sysUserService;
@GetMapping(value="/findByUserId")publicObject findByUserId(@RequestParam Long userId) {returnsysUserService.findByUserId(userId);
}
@GetMapping(value="/findAll")publicObject findAll() {returnsysUserService.findAll();
}
@PostMapping(value="/findPage")publicObject findPage(@RequestBody PageRequest pageQuery) {returnsysUserService.findPage(pageQuery);
}
}
分页查询请求封装类。
PageRequest.java
packagecom.louis.springboot.demo.util;/*** 分页请求*/
public classPageRequest {/*** 当前页码*/
private intpageNum;/*** 每页数量*/
private intpageSize;public intgetPageNum() {returnpageNum;
}public void setPageNum(intpageNum) {this.pageNum =pageNum;
}public intgetPageSize() {returnpageSize;
}public void setPageSize(intpageSize) {this.pageSize =pageSize;
}
}
分页查询结果封装类。
PageResult.java
packagecom.louis.springboot.demo.util;importjava.util.List;/*** 分页返回结果*/
public classPageResult {/*** 当前页码*/
private intpageNum;/*** 每页数量*/
private intpageSize;/*** 记录总数*/
private longtotalSize;/*** 页码总数*/
private inttotalPages;/*** 数据模型*/
private List>content;public intgetPageNum() {returnpageNum;
}public void setPageNum(intpageNum) {this.pageNum =pageNum;
}public intgetPageSize() {returnpageSize;
}public void setPageSize(intpageSize) {this.pageSize =pageSize;
}public longgetTotalSize() {returntotalSize;
}public void setTotalSize(longtotalSize) {this.totalSize =totalSize;
}public intgetTotalPages() {returntotalPages;
}public void setTotalPages(inttotalPages) {this.totalPages =totalPages;
}public List>getContent() {returncontent;
}public void setContent(List>content) {this.content =content;
}
}
分页查询相关工具类。
PageUtils.java
packagecom.louis.springboot.demo.util;importcom.github.pagehelper.PageInfo;public classPageUtils {/*** 将分页信息封装到统一的接口
*@parampageRequest
*@parampage
*@return
*/
public static PageResult getPageResult(PageRequest pageRequest, PageInfo>pageInfo) {
PageResult pageResult= newPageResult();
pageResult.setPageNum(pageInfo.getPageNum());
pageResult.setPageSize(pageInfo.getPageSize());
pageResult.setTotalSize(pageInfo.getTotal());
pageResult.setTotalPages(pageInfo.getPages());
pageResult.setContent(pageInfo.getList());returnpageResult;
}
}
编译测试运行
参数:pageNum: 1, pageSize: 5
参数:pageNum: 2, pageSize: 4
胡言乱语
传统分页有点老,select和count都得搞。
分页SQL写不好,内容耦合还不小。
pagehelper帮你搞,使用起来有点屌。
参考资料
相关导航
源码下载