綜合概述
想必大家都有過這樣的體驗,在使用Mybatis時,最頭痛的就是寫分頁了,需要先寫一個查詢count的select語句,然后再寫一個真正分頁查詢的語句,當查詢條件多了之后,會發現真的不想花雙倍的時間寫 count 和 select,幸好我們有 pagehelper 分頁插件,pagehelper 是一個強大實用的 MyBatis 分頁插件,可以幫助我們快速的實現MyBatis分頁功能,而且pagehelper有個優點是,分頁和Mapper.xml完全解耦,並以插件的形式實現,對Mybatis執行的流程進行了強化,這有效的避免了我們需要直接寫分頁SQL語句來實現分頁功能。那么,接下來我們就來一起體驗下吧。
實現案例
接下來,我們就通過實際案例來講解如何使用pagehelper來實現MyBatis分頁,為了避免重復篇幅,此篇教程的源碼基於《Spring Boot:整合MyBatis框架》一篇的源碼實現,讀者請先參考並根據教程鏈接先行獲取基礎源碼和數據庫內容。
添加相關依賴
首先,我們需要在 pom.xml 文件中添加分頁插件依賴包。
pom.xml
<!-- pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency>
添加相關配置
然后在 application.yml 配置文件中添加分頁插件有關的配置。
application.yml
# pagehelper pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql
編寫分頁代碼
首先,在 DAO 層添加一個分頁查找方法。這個查詢方法跟查詢全部數據的方法除了名稱幾乎一樣。
SysUserMapper.java
package com.louis.springboot.demo.dao; import java.util.List; import com.louis.springboot.demo.model.SysUser; public interface SysUserMapper { int deleteByPrimaryKey(Long id); int insert(SysUser record); int insertSelective(SysUser record); SysUser selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(SysUser record); int updateByPrimaryKey(SysUser record); /** * 查詢全部用戶 * @return */ List<SysUser> selectAll(); /** * 分頁查詢用戶 * @return */ List<SysUser> selectPage(); }
然后在 SysUserMapper.xml 中加入selectPage的實現,當然你也可以直接用@Select注解將查詢語句直接寫在DAO代碼,但我們這里選擇寫在XML映射文件,這是一個普通的查找全部記錄的查詢語句,並不需要寫分頁SQL,分頁插件會攔截查詢請求,並讀取前台傳來的分頁查詢參數重新生成分頁查詢語句。
SysUserMapper.xml
<select id="selectPage" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from sys_user </select>
服務層通過調用DAO層代碼完成分頁查詢,這里統一封裝分頁查詢的請求和結果類,從而避免因為替換ORM框架而導致服務層、控制層的分頁接口也需要變動的情況,替換ORM框架也不會影響服務層以上的分頁接口,起到了解耦的作用。
SysUserService.java
package com.louis.springboot.demo.service; import java.util.List; import com.louis.springboot.demo.model.SysUser; import com.louis.springboot.demo.util.PageRequest; import com.louis.springboot.demo.util.PageResult; public interface SysUserService { /** * 根據用戶ID查找用戶 * @param userId * @return */ SysUser findByUserId(Long userId); /** * 查找所有用戶 * @return */ List<SysUser> findAll(); /** * 分頁查詢接口 * 這里統一封裝了分頁請求和結果,避免直接引入具體框架的分頁對象, 如MyBatis或JPA的分頁對象 * 從而避免因為替換ORM框架而導致服務層、控制層的分頁接口也需要變動的情況,替換ORM框架也不會 * 影響服務層以上的分頁接口,起到了解耦的作用 * @param pageRequest 自定義,統一分頁查詢請求 * @return PageResult 自定義,統一分頁查詢結果 */ PageResult findPage(PageRequest pageRequest); }
服務實現類通過調用分頁插件完成最終的分頁查詢,關鍵代碼是 PageHelper.startPage(pageNum, pageSize),將前台分頁查詢參數傳入並攔截MyBtis執行實現分頁效果。
SysUserServiceImpl.java
package com.louis.springboot.demo.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.louis.springboot.demo.dao.SysUserMapper; import com.louis.springboot.demo.model.SysUser; import com.louis.springboot.demo.service.SysUserService; import com.louis.springboot.demo.util.PageRequest; import com.louis.springboot.demo.util.PageResult; import com.louis.springboot.demo.util.PageUtils; @Service public class SysUserServiceImpl implements SysUserService { @Autowired private SysUserMapper sysUserMapper; @Override public SysUser findByUserId(Long userId) { return sysUserMapper.selectByPrimaryKey(userId); } @Override public List<SysUser> findAll() { return sysUserMapper.selectAll(); } @Override public PageResult findPage(PageRequest pageRequest) { return PageUtils.getPageResult(pageRequest, getPageInfo(pageRequest)); } /** * 調用分頁插件完成分頁 * @param pageQuery * @return */ private PageInfo<SysUser> getPageInfo(PageRequest pageRequest) { int pageNum = pageRequest.getPageNum(); int pageSize = pageRequest.getPageSize(); PageHelper.startPage(pageNum, pageSize); List<SysUser> sysMenus = sysUserMapper.selectPage(); return new PageInfo<SysUser>(sysMenus); } }
在控制器SysUserController中添加分頁查詢方法,並調用服務層的分頁查詢方法。
SysUserController.java
package com.louis.springboot.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.louis.springboot.demo.service.SysUserService; import com.louis.springboot.demo.util.PageRequest; @RestController @RequestMapping("user") public class SysUserController { @Autowired private SysUserService sysUserService; @GetMapping(value="/findByUserId") public Object findByUserId(@RequestParam Long userId) { return sysUserService.findByUserId(userId); } @GetMapping(value="/findAll") public Object findAll() { return sysUserService.findAll(); } @PostMapping(value="/findPage") public Object findPage(@RequestBody PageRequest pageQuery) { return sysUserService.findPage(pageQuery); } }
分頁查詢請求封裝類。
PageRequest.java
package com.louis.springboot.demo.util; /** * 分頁請求 */ public class PageRequest { /** * 當前頁碼 */ private int pageNum; /** * 每頁數量 */ private int pageSize; 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; } }
分頁查詢結果封裝類。
PageResult.java
package com.louis.springboot.demo.util; import java.util.List; /** * 分頁返回結果 */ public class PageResult { /** * 當前頁碼 */ private int pageNum; /** * 每頁數量 */ private int pageSize; /** * 記錄總數 */ private long totalSize; /** * 頁碼總數 */ private int totalPages; /** * 數據模型 */ private List<?> content; 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 long getTotalSize() { return totalSize; } public void setTotalSize(long totalSize) { this.totalSize = totalSize; } public int getTotalPages() { return totalPages; } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } public List<?> getContent() { return content; } public void setContent(List<?> content) { this.content = content; } }
分頁查詢相關工具類。
PageUtils.java
package com.louis.springboot.demo.util; import com.github.pagehelper.PageInfo; public class PageUtils { /** * 將分頁信息封裝到統一的接口 * @param pageRequest * @param page * @return */ public static PageResult getPageResult(PageRequest pageRequest, PageInfo<?> pageInfo) { PageResult pageResult = new PageResult(); pageResult.setPageNum(pageInfo.getPageNum()); pageResult.setPageSize(pageInfo.getPageSize()); pageResult.setTotalSize(pageInfo.getTotal()); pageResult.setTotalPages(pageInfo.getPages()); pageResult.setContent(pageInfo.getList()); return pageResult; } }
編譯測試運行
啟動應用,訪問:localhost:8088/swagger-ui.html,找到對應接口,模擬測試,結果如下。
參數:pageNum: 1, pageSize: 5
參數:pageNum: 2, pageSize: 4
胡言亂語
傳統分頁有點老,select和count都得搞。
分頁SQL寫不好,內容耦合還不小。
pagehelper幫你搞,使用起來有點屌。
參考資料
PageHelper:https://pagehelper.github.io/
PageHelper手冊:https://pagehelper.github.io/docs/howtouse/
相關導航
源碼下載
碼雲:https://gitee.com/liuge1988/spring-boot-demo.git
作者:朝雨憶輕塵
出處:https://www.cnblogs.com/xifengxiaoma/
版權所有,歡迎轉載,轉載請注明原文作者及出處。