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更高級。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章