1. 程式人生 > >Spring Data之Slice分頁查詢

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