在java中实现分页的方式有几种主要方式,可以根据场景选择合适的分页方式。
1. 数据库层分页
在sql查询时,使用limit和offset进行分页,
mysql分页
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20;
等价于
SELECT * FROM users ORDER BY id LIMIT 20, 10;
limit : 10 表示查询10条数据
offset: 20 表示跳过前20条数据
在mybatis-plus中使用分页
IPage<User> page = new Page<>(2, 10); // 第 2 页,每页 10 条
IPage<User> userPage = userMapper.selectPage(page, null);
List<User> users = userPage.getRecords();
public PageDto<User> getUsers (pageIndex,pageSize){
PageDto<User> result = new PageDto<>();
result.setPageIndex(pageIndex);
result.setPageSize(pageSize);
Page<User> page = new Page<>(pageIndex, pageSize);
List<User> user;
IPage<User> users= Service.getUsers(page, params);
result.setPageCount((int) users.getPages());
result.setDataCount((int) users.getTotal());
user= users.getRecords();
result.setData(user);
return result;
}
优点:
直接在数据库处理分页,效率高。
适用于大数据量分页,不需要在java内存中处理大量数据。
缺点:
适用于查询速度较快的数据库,否则大数据量情况下offset会导致性能下降。
2. 物理分页
在数据量不大的情况下,可以手动截取List()进行分页。
使用subList()
public PageDto<User> getUsers (pageIndex,pageSize){
List<User> users = useService.getUsers();
int totalPages = (users .size() + pageSize - 1) / pageSize;
// 计算需要查询的数据范围
int startIndex = (pageIndex - 1) * pageSize;
int endIndex = Math.min(startIndex + pageSize, users .size());
List<User> pagedResponses = users.subList(startIndex, endIndex);
PageInfo<User> pageInfo = new PageInfo<>(users);
int totalCount = (int) pageInfo.getTotal();
PageDto<User> result = new PageDto<>();
result.setPageIndex(pageIndex);
result.setPageCount(totalPages);
result.setDataCount(totalCount);
result.setPageSize(pageSize);
result.setData(pagedResponses);
return result;
}
适用于小数据量进行分页
大数据量不适合,会导致oom(内存溢出)
3. 使用spring data jpa 进行分页
Spring Data JPA 提供了 Pageable
接口,可以直接在数据库中进行分页
Pageable pageable = PageRequest.of(1, 10);
Page<User> usersPage = userRepository.findAll(pageable);
List<User> users = usersPage.getContent();
4. 使用PageHelper分页,(mybatis推荐)
PageHelper 是 MyBatis 的分页插件,可以自动处理 SQL 分页。
public PageDto<User> getUsers(Integer pageIndex,Integer pageSize){
PageHeper.startPage(pageIndex,pageSize);
List<User> users = userServicce.getUsers();
PageInfo<User> userPageInfos = new PageInfo<>(Users);
PageDto<User> result = new PageDto<>();
result.setPageIndex(userPageInfos .getPageNum());
result.setPageCount(userPageInfos .getPages());
result.setDataCount((int) userPageInfos .getTotal());
result.setPageSize(userPageInfos .getPageSize());
result.setData(users);
return result;
}
5. redis + 分页
如果数据存在redis中,(如排行榜、缓存分页等),可以使用 ZRANGE
进行分页。
Set<String> result = redisTemplate.opsForZSet().range("ranking", 10, 19);
✅ 适用于高并发数据分页,如排行榜、热榜等 ❌ 只能分页 Redis 数据,不能用于数据库查询