Spring Data之Slice分页查询

背景

项目中我们经常用到分页查询,一般使用的场景有两个

  1. 前端查询大批量数据时指定page、size分页查询

  2. 后台定时处理一批数据时,从数据库获取待处理数据,从而避免一次查询太多数据到内存,处理完一批后再查询下一页的数据处理

对于场景2也有两种实现方式,Page和Slice,下面就分别介绍

Page

public interface UserRepository extends JpaRepository<User,Long> {
    Page<User> findByAge(int age, Pageable pageable);
}

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class JpaTests {
	@Autowired
    private UserRepository userRepository;
    
	@Before
    public void before(){

        userRepository.saveAll(Arrays.asList(
                new User(null,"刘","一", 20),
                new User(null,"陈","二", 20),
                new User(null,"张","三", 20),
                new User(null,"李","四", 20),
                new User(null,"王","五", 20),
                new User(null,"赵","六", 20),
                new User(null,"孙","七", 20),
                new User(null,"周","八", 20)
        ));
    }
    
	@Test
    public void queryByPage(){
        int pageNum = 0;
        while(true){
            Pageable pageable = PageRequest.of(pageNum, 3);
            Page<User> page = userRepository.findByAge(20, pageable);
            List<User> users = page.getContent();
            users.forEach(System.out::println);

            if (users.size() == 0){
                break;
            }

            pageNum++;
        }
    }
}

控制台输出

Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.first_name as first_na3_0_, user0_.last_name as last_nam4_0_ from t_user user0_ where user0_.age=? limit ?
Hibernate: select count(user0_.id) as col_0_0_ from t_user user0_ where user0_.age=?
User(id=1, firstName=, lastName=, age=20)
User(id=2, firstName=, lastName=, age=20)
User(id=3, firstName=, lastName=, age=20)
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.first_name as first_na3_0_, user0_.last_name as last_nam4_0_ from t_user user0_ where user0_.age=? limit ? offset ?
Hibernate: select count(user0_.id) as col_0_0_ from t_user user0_ where user0_.age=?
User(id=4, firstName=, lastName=, age=20)
User(id=5, firstName=, lastName=, age=20)
User(id=6, firstName=, lastName=, age=20)
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.first_name as first_na3_0_, user0_.last_name as last_nam4_0_ from t_user user0_ where user0_.age=? limit ? offset ?
User(id=7, firstName=, lastName=, age=20)
User(id=8, firstName=, lastName=, age=20)

代码比较简单,就是循环增加pageNum,只到查询为空就终止

Slice

Slice是一个数据块,表明是否有更多可用数据,能够循环的获取数据。

@Test
    public void queryBySlice(){
        Pageable pageable = PageRequest.of(0,3);
        while(true){
           Slice<User> slice = userRepository.findByAge(20, pageable);
           List<User> users = slice.getContent();
           users.forEach(System.out::println);

           if (!slice.hasNext()){
               break;
           }

           pageable = slice.nextPageable();
        }
    }

可以看到跟Page的区别是,不需要自定义的判断是否有数据,也不用自己累加页数了。使用slice.hasNext()就能判断是否还有下一个Slice,这里要注意需要调用slice.nextPageable()获取下一个pageable,怎么样看起来是不是比Page更高级。

猜你喜欢

转载自blog.csdn.net/f4761/article/details/84398526