Java中常见分页方式有哪些

在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. queryWrapper 分页

public PageDto<User> getUserListPageByKeyWord(String keyWord, Integer pageIndex, Integer pageSize) {
        PageDto<User> result = new PageDto<>();
        Page<User> page = new Page<>(pageIndex, pageSize);

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<User> lambdaQueryWrapper = queryWrapper.lambda();
        lambdaQueryWrapper.eq(User::getStatus, 1);

        if (StringUtils.isNotEmpty(keyWord)){
            lambdaQueryWrapper.and(
                    wrapper -> wrapper
                            .like(User:: getName, keyWord)
            );
        }

        lambdaQueryWrapper.orderByDesc(User::getID);

        IPage<User> standardPage = this.baseMapper.selectPage(page, queryWrapper);
        List<User>  modelList = standardPage.getRecords();

        result.setPageCount(Integer.parseInt("" + standardPage.getPages()));
        result.setDataCount(Integer.parseInt("" + standardPage.getTotal()));

        result.setData(modelList);
        result.setPageIndex(pageIndex);
        result.setPageSize(pageSize);

        return result;
    }

6. redis + 分页

如果数据存在redis中,(如排行榜、缓存分页等),可以使用 ZRANGE 进行分页。

Set<String> result = redisTemplate.opsForZSet().range("ranking", 10, 19);

适用于高并发数据分页,如排行榜、热榜等只能分页 Redis 数据,不能用于数据库查询


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值