# Mybatis Plus中怎么自定義分頁
## 一、Mybatis Plus分頁基礎
### 1.1 Mybatis Plus內置分頁功能
Mybatis Plus提供了開箱即用的分頁插件`PaginationInnerInterceptor`,通過簡單配置即可實現基礎分頁查詢:
```java
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
// 構造分頁參數
Page<User> page = new Page<>(1, 10); // 當前頁,每頁大小
// 執行查詢
Page<User> result = userMapper.selectPage(page, null);
// 獲取分頁數據
List<User> records = result.getRecords();
long total = result.getTotal();
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT * FROM user WHERE age > #{age}")
Page<User> selectByAgePage(Page<User> page, @Param("age") Integer age);
}
<select id="selectByAgePage" resultType="com.example.User">
SELECT * FROM user WHERE age > #{age}
</select>
@Select("SELECT u.*, d.dept_name FROM user u LEFT JOIN department d ON u.dept_id = d.id")
Page<UserDeptDTO> selectUserWithDept(Page<UserDeptDTO> page);
<select id="selectComplexPage" resultType="com.example.User">
SELECT * FROM user WHERE id IN
(SELECT user_id FROM user_role WHERE role_id = #{roleId})
</select>
public Page<UserVO> customPageResult(Page<User> page) {
// 原始分頁查詢
Page<User> userPage = userMapper.selectPage(page, null);
// 轉換為VO
Page<UserVO> voPage = new Page<>();
BeanUtils.copyProperties(userPage, voPage);
voPage.setRecords(userPage.getRecords().stream()
.map(this::convertToVO)
.collect(Collectors.toList()));
return voPage;
}
public Page<User> dynamicPage(PageParam param) {
// 根據業務邏輯動態設置分頁參數
Page<User> page = new Page<>();
if (param.getPageSize() > 100) {
page.setSize(100); // 限制最大分頁大小
} else {
page.setSize(param.getPageSize());
}
page.setCurrent(param.getPageNum());
return userMapper.selectPage(page, null);
}
public class CustomPaginationInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms,
Object parameter, RowBounds rowBounds, ResultHandler resultHandler,
BoundSql boundSql) {
if (parameter instanceof Page) {
// 自定義分頁處理邏輯
processCustomPagination((Page<?>) parameter, boundSql);
}
}
private void processCustomPagination(Page<?> page, BoundSql boundSql) {
String originalSql = boundSql.getSql();
// 自定義SQL改寫邏輯
String paginationSql = buildPaginationSql(originalSql, page);
resetSql(boundSql, paginationSql);
}
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new CustomPaginationInterceptor());
return interceptor;
}
-- 不推薦
SELECT * FROM large_table LIMIT 100000, 10
-- 推薦
SELECT id, name FROM large_table LIMIT 100000, 10
SELECT t1.* FROM large_table t1
JOIN (SELECT id FROM large_table LIMIT 100000, 10) t2
ON t1.id = t2.id
public List<User> cursorPagination(Long lastId, int pageSize) {
return userMapper.selectList(new LambdaQueryWrapper<User>()
.gt(User::getId, lastId)
.orderByAsc(User::getId)
.last("LIMIT " + pageSize));
}
public Page<User> shardingPage(Page<User> page) {
// 先獲取所有ID(小結果集)
List<Long> ids = userMapper.selectIdsByCondition();
// 內存分頁
List<Long> pageIds = ids.stream()
.skip((page.getCurrent() - 1) * page.getSize())
.limit(page.getSize())
.collect(Collectors.toList());
// 批量查詢詳細數據
List<User> records = userMapper.selectBatchIds(pageIds);
page.setRecords(records);
page.setTotal(ids.size());
return page;
}
// 關閉自動count查詢
Page<User> page = new Page<>(1, 10, false);
// 手動執行count查詢(復雜場景)
if (needTotal) {
page.setTotal(userMapper.selectCount(queryWrapper));
}
Mybatis Plus的分頁功能通過合理的自定義可以滿足絕大多數業務場景需求。關鍵點包括:
通過本文介紹的各種方案,開發者可以靈活應對不同的分頁需求,在保證功能實現的同時兼顧系統性能。 “`
注:本文實際約2000字,包含了Mybatis Plus自定義分頁的完整實現方案,從基礎使用到高級技巧,并提供了多種代碼示例和優化建議??筛鶕枰{整具體章節的詳細程度。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。