PageHeper
PageHelper 是一個非常流行的 MyBatis 分頁插件,主要用于簡化分頁查詢的實現。使用 PageHelper 可以在執行數據庫查詢時,自動處理分頁參數,從而避免手動編寫繁瑣的分頁邏輯。
今天就來學習一下PageHelper的相關知識和用法!
PageHelper
主要功能
- 分頁查詢:通過
PageHelper.startPage()方法指定頁碼和每頁的大小,之后執行的查詢會自動分頁。 - 排序功能:支持排序功能,分頁查詢時可以通過指定排序字段和排序方式來獲得排序后的結果集。
- 簡化分頁邏輯:無需手動修改 SQL 語句,
PageHelper會自動為查詢 SQL 添加分頁邏輯,大大簡化代碼。 - 多數據庫支持:
PageHelper支持多種主流的數據庫,如 MySQL、Oracle、PostgreSQL 等。
使用步驟
-
引入依賴
在pom.xml中添加PageHelper依賴:<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency> -
配置攔截器
在 MyBatis 配置文件或配置類中,注冊PageHelper攔截器:@Bean public PageInterceptor pageHelper() { PageInterceptor pageInterceptor = new PageInterceptor(); Properties properties = new Properties(); properties.setProperty("helperDialect", "mysql"); // 數據庫類型 pageInterceptor.setProperties(properties); return pageInterceptor; } -
分頁查詢使用示例
在代碼中使用PageHelper.startPage()方法來指定分頁參數,后續的查詢會自動帶上分頁信息:@Service public class UserService { @Autowired private UserMapper userMapper; public List<User> getUsers(int pageNum, int pageSize) { // 開啟分頁 PageHelper.startPage(pageNum, pageSize); // 查詢結果 return userMapper.getAllUsers(); } } -
返回分頁結果
使用PageInfo來包裝分頁結果,包含分頁信息和查詢結果:List<User> userList = userMapper.getAllUsers(); PageInfo<User> pageInfo = new PageInfo<>(userList); System.out.println(pageInfo.getTotal()); // 總記錄數 System.out.println(pageInfo.getList()); // 當前頁的記錄列表
核心方法
PageHelper.startPage(int pageNum, int pageSize):指定頁碼和每頁大小,之后的查詢會自動分頁。PageHelper.orderBy(String orderBy):設置排序規則,如"id desc",按id倒序排列。PageInfo<T>:封裝分頁結果信息,包含總記錄數、總頁數、當前頁的記錄等。
總結
PageHelper 提供了一種簡潔的方式來實現 MyBatis 的分頁查詢,自動處理分頁邏輯并簡化代碼,同時支持多種數據庫和排序功能,是 MyBatis 用戶進行分頁查詢的一個常用工具。
SpringBoot中的PageHelper
pagehelper-spring-boot-starter 是 PageHelper 的 Spring Boot 自動配置版本,能夠更簡便地集成 PageHelper,特別是在 Spring Boot 項目中。相比于手動配置 PageHelper,使用 pagehelper-spring-boot-starter 可以進一步簡化配置和使用過程。
使用步驟
-
引入依賴
在 Spring Boot 項目的pom.xml中添加pagehelper-spring-boot-starter依賴:<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.6</version> </dependency> -
自動配置
引入pagehelper-spring-boot-starter后,不需要手動配置PageHelper攔截器,Spring Boot 會自動配置好分頁插件。 -
在查詢方法中使用
使用PageHelper.startPage()方法指定分頁參數,在執行查詢時,結果會自動分頁。示例代碼:
@Service public class UserService { @Autowired private UserMapper userMapper; // 分頁獲取用戶列表 public PageInfo<User> getUsers(int pageNum, int pageSize) { // 設置分頁參數 PageHelper.startPage(pageNum, pageSize); // 執行查詢,得到結果集 List<User> users = userMapper.getAllUsers(); // 使用PageInfo來封裝分頁信息 return new PageInfo<>(users); } } -
返回分頁結果
PageInfo是PageHelper提供的工具類,用于封裝分頁信息,如總記錄數、總頁數、當前頁數據等。可以通過PageInfo對象獲取到這些信息:PageInfo<User> pageInfo = userService.getUsers(1, 10); System.out.println(pageInfo.getTotal()); // 獲取總記錄數 System.out.println(pageInfo.getPages()); // 獲取總頁數 System.out.println(pageInfo.getList()); // 獲取當前頁的數據 -
自定義配置(可選)
你可以通過 Spring Boot 的application.properties或application.yml文件自定義PageHelper的相關配置,比如數據庫方言、合理化配置、分頁方式等。在
application.yml中添加自定義配置:pagehelper: helper-dialect: mysql # 數據庫方言 reasonable: true # 啟用合理化,避免頁碼超出范圍 support-methods-arguments: true # 支持分頁參數作為方法參數 params: count=countSql # 分頁查詢時統計總數的SQL或者在
application.properties中:pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql
復雜度
- 時間復雜度:分頁查詢的時間復雜度依賴于數據庫查詢操作。一般情況下,查詢復雜度為 $O(n)$,加上分頁條件,實際執行時可能會根據數據庫的索引和優化機制有所不同。
- 空間復雜度:空間復雜度取決于分頁結果和數據的存儲形式,一般為 $O(k)$,其中
k是每頁返回的數據量。
總結
通過 pagehelper-spring-boot-starter,在 Spring Boot 項目中可以輕松集成 PageHelper,自動完成分頁查詢的配置和操作,簡化了開發者的代碼量。同時還支持自定義配置,能夠靈活應對各種分頁需求。
實際運用
在我正在寫的仿12306項目中很多地方都會用到pagehelper,所以一般會封裝分頁查詢的入參和出參類,就以查詢乘車人為例:
PageReq
封裝PageReq作為分頁查詢入參類的父類,為分頁查詢提供pageNum和pageSize;
PageReq
public class PageReq {
@NotNull(message = "【頁碼】不能為空")
private Integer start;
@NotNull(message = "【每頁條數】不能為空")
@Max(value = 100, message = "【每頁條數】不能超過100")
private Integer count;
public @NotNull(message = "【頁碼】不能為空") Integer getStart() {
return start;
}
public void setStart(@NotNull(message = "【頁碼】不能為空") Integer start) {
this.start = start;
}
public @NotNull(message = "【每頁條數】不能為空") @Max(value = 100, message = "【每頁條數】不能超過100") Integer getCount() {
return count;
}
public void setCount(@NotNull(message = "【每頁條數】不能為空") @Max(value = 100, message = "【每頁條數】不能超過100") Integer count) {
this.count = count;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("pageReq{");
sb.append("start=").append(start);
sb.append(", count=").append(count);
sb.append('}');
return sb.toString();
}
}
查詢乘車人服務的入參類繼承PageReq類;
PassengerQueryReq
public class PassengerQueryReq extends PageReq {
private Long memberId;
private String idCard;
public Long getMemberId() {
return memberId;
}
public void setMemberId(Long memberId) {
this.memberId = memberId;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("PassengerQueryReq{");
sb.append("memberId=").append(memberId);
sb.append(", idCard='").append(idCard).append('\'');
sb.append('}');
return sb.toString();
}
}
在查詢乘車人服務中使用PageReq提供的pageNum和pageSize調用PageHelper;
PassengerService
@Service
public class PassengerService {
@Resource
private PassengerMapper passengerMapper;
public List<PassengerQueryResp> queryList (PassengerQueryReq req) {
PassengerExample passengerExample = new PassengerExample();
PassengerExample.Criteria criteria = passengerExample.createCriteria();
if (ObjectUtil.isNotNull(req.getMemberId())) {
criteria.andMemberIdEqualTo(req.getMemberId());
}
PageHelper.startPage(req.getStart(), req.getCount());
List<Passenger> passengerList = passengerMapper.selectByExample(passengerExample);
return BeanUtil.copyToList(passengerList, PassengerQueryResp.class);
}
public void update(PassengerSaveReq req) {
DateTime now = DateTime.now();
Passenger passenger = BeanUtil.copyProperties(req, Passenger.class);
passenger.setMemberId(LoginMemberContext.getId());
passenger.setModifiedTime(now);
PassengerExample passengerExample = new PassengerExample();
passengerExample.createCriteria().
andMemberIdEqualTo(passenger.getMemberId()).
andIdCardEqualTo(passenger.getIdCard());
passengerMapper.updateByExampleSelective(passenger, passengerExample);
}
}
PageResp
封裝PageResp作為response類,返回查詢總數、分頁總數和查詢列表;
PageResp
public class PageResp<T> implements Serializable {
private static final Long serialVersionUID = 1L;
/**
* 查詢結果總數
*/
private Long total;
/**
* 查詢結果列表
*/
private List<T> list;
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("PageResp{");
sb.append("total=").append(total);
sb.append(", list=").append(list);
sb.append('}');
return sb.toString();
}
}
查詢乘車人服務中使用PageInfo獲取分頁查詢的結果總數和分頁數,返回PageResp;
PassengerService
@Service
public class PassengerService {
private static final Logger LOG = LoggerFactory.getLogger(PassengerService.class);
@Resource
private PassengerMapper passengerMapper;
public PageResp<PassengerQueryResp> queryList (PassengerQueryReq req) {
PassengerExample passengerExample = new PassengerExample();
PassengerExample.Criteria criteria = passengerExample.createCriteria();
if (ObjectUtil.isNotNull(req.getMemberId())) {
criteria.andMemberIdEqualTo(req.getMemberId());
}
// mybatis PageHelper分頁查詢
LOG.info("查詢頁碼:{}", req.getStart());
LOG.info("每頁條數:{}", req.getCount());
PageHelper.startPage(req.getStart(), req.getCount());
List<Passenger> passengerList = passengerMapper.selectByExample(passengerExample);
// 把passengerList轉為passengerQueryRespList
List<PassengerQueryResp> passengerQueryResp = BeanUtil.copyToList(passengerList, PassengerQueryResp.class);
// pageHelper獲取分頁查詢總條數,將分頁查詢結果(條數+list)封裝到pageResp
PageInfo<Passenger> pageInfo = new PageInfo<>(passengerList);
LOG.info("總條數:{}", pageInfo.getTotal());
LOG.info("總頁數:{}", pageInfo.getPages());
PageResp<PassengerQueryResp> pageResp = new PageResp<>();
pageResp.setList(passengerQueryResp);
pageResp.setTotal(pageInfo.getTotal());
return pageResp;
}
}

浙公網安備 33010602011771號