網頁

2019/9/21

Spring Data JPA 分頁及排序查詢範例 pagination and sorting query example

Spring Data JPA 分頁及排序查詢簡單範例如下。


Message是要被查詢的Entity類,映射資料庫的MESSAGE資料表。
等一下查詢時將以CREATE_TIME欄位來排序。

Message

package com.abc.demo.entity;

import javax.persistence.Entity
import javax.persistence.Table
import javax.persistence.Id
import javax.persistence.Column

@Entity
@Table(name="MESSAGE")
public class Message {

    @Id
    @Column("ID")
    private String id;

    @Column("CONTENT")
    private String content;

    @Column("CREATE_TIME")   // <-- sort by this column
    private Long createTime;

    // getters and setters...
    
}

MessageRepository用來存取資料庫的Repository類,繼承JpaRepository<T, ID>,其Spring Data JPA的實作子類SimpleJpaRepository提供了分頁查詢方法如findAll(Pageable pageable)

MessageRepository

package com.abc.demo.repository;

import org.springframework.data.jpa.repository
import org.springframework.stereotype.Repository;

import com.abc.demo.entity.Message;

@Repository
public interface MessageRepository extends JpaRepository<Message, String> {

}

下面為使用PageRequest.of(int page, int size, Sort sort)搭配Sort來對資料庫做分頁及排序查詢。

注意page是zero-based index,也就是第一頁是從0起算。

MessageDao

package com.abc.demo.dao;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.abc.demo.entity.Message;
import com.abc.demo.repository.MessageRepository

@Service
public class MessageDao {

    @Autowired
    private MessageRepository messageRepository

    public List<Message> getPagedMessages(int page, int size) {
    
        Page<Message> pageResult = messageRepository.findAll(
                PageRequest.of(page,  // 查詢的頁數,從0起算
                                size, // 查詢的每頁筆數
                                Sort.by("createTime").descending())); // 依CREATE_TIME欄位降冪排序
        
        pageResult.getNumberOfElements(); // 本頁筆數
        pageResult.getSize();             // 每頁筆數 
        pageResult.getTotalElements();    // 全部筆數
        pageResult.getTotalPages();       // 全部頁數
        
        List<Message> messageList =  pageResult.getContent();
    
        return messageList;
    
    }

}

返回的Page物件中除了裝載了查詢結果外,還可取得該筆分頁的資訊如查詢筆數等。


參考:

5 則留言:

  1. 您好
    同樣在做分頁排序的功能,
    但jpa字段的驗證困擾我許久,
    始終沒找到解法,還勞煩百忙之中能為我解惑。

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Integer user_id;

    Page pageResult = userDao.findAll(
    PageRequest.of(
    page,
    size,
    Sort.by("createTime")
    ));

    No property createTime found for type UserModel! Did you mean 'create_time'?

    是否有什麼額外的設定沒做到呢?

    回覆刪除
  2. Hi 樓上,根據訊息您的entity類UserModel中沒有createTime的欄位,所以你用SortBy("createTime")會出現找不到createTime欄位的錯誤,也可能你的column的mapping名稱不一致。

    回覆刪除
  3. 啊啊 抱歉 很不好意思 我貼錯code了 !!!
    我是要 sort user_id 沒錯

    class UserModel implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Integer user_id;

    Page pageResult = userDao.findAll(
    PageRequest.of(
    page,
    size,
    Sort.by("userId")
    ));

    嘗試用 userId:
    No property userId found for type UserModel! Did you mean 'user_id'?


    嘗試用 user_id:
    No property found for type UserModel!

    各種奇奇怪怪的組合都無法,也是過用 JpaSort.unsafe 也是如此

    回覆刪除
  4. 你的@Column設定的名稱為"user_id",所以你要改用Sort.by("user_id")才行喔。

    回覆刪除
  5. 了解.. 謝謝您費心回覆我
    我也覺得應該是要照 @Column 中的字段才對
    不過嘗試了user_id 或 userId 等等 各種奇奇怪怪的字段組合
    還是會出現
    No property found for type UserMode
    或是
    No property userId found for type UserModel! Did you mean 'user_id'?
    看到有人嘗試用 JpaSort.unsafe 但我的情境依舊會報錯
    我想只能忍痛改掉實體類字段了:(

    回覆刪除