2011-04-20 33 views
1

假設我們有一個實體用戶,它有很多評論。 它是可以這樣做:如何檢索相關實體的有限集合?

List<Comment> = user.getComments(); 

但是,這將載入所有的用戶的評論。 我們應該如何檢索前10個例子? 是類似的東西:

List<Comment> = user.getComments().setOffset(0).stLimit(10).getResultList(); 

回答

1

標準Java辦法做到這一點(我敢確保JPA提供商具有支持該功能的功能)是:

List<Comment> = user.getComments().subList(0,10); 

參考


或者你可以使用非常冗長的JPA 2 CriteriaQuery API:

CriteriaQuery<Comment> cQuery = 
     entityManager.getCriteriaBuilder() 
        .createQuery(Comment.class); 
cQuery.select(cQuery.from(Customer.class) 
        .get(Customer_.comments)); 
List<Comment> comments = 
     entityManager.createQuery(cQuery) 
        .setFirstResult(0) 
        .setMaxResults(0) 
        .getResultList(); 
+1

我知道,但在我得到子列表之前,JPA會加載**所有**一些用戶的評論:你應該同意如果用戶有1mil的評論 – 2011-04-20 14:44:46

+0

@userXXX * JPA會加載一些用戶* Nope的所有評論如果你使用延遲加載,提供者將加載一個代理列表來創建一個新的代理列表對於subList()。實際的查詢只會在您訪問列表條目時執行。但是AFAIK在JPA標準中沒有正式定義。如果我正確地閱讀Hibernate源代碼,Hibernate會這樣做,但不能保證。 @克里斯蒂安的方式肯定是比較安全的,但它也更難看 – 2011-04-20 14:49:11

+0

哦,不知道。我會試試看... – 2011-04-20 14:52:29

2

您應該在查詢中使用LIMIT而不是在代碼中對此進行限制。

如:

SELECT comment.id, comment.name FROM comment WHERE comment.name =:username 
ORDER BY comment.id DESC LIMIT 10; 

或者您也可以使用來自JPA setMaxResults方法:文檔here

如:

Query query=em.createQuery("SELECT st FROM Student st WHERE st.sroll > ?param"); 
query.setParameter(param, 100); 
query.setMaxResults(3); 
List stuList=query.getResultList(); 
+0

因此,有沒有這樣的內置功能實現這一點,就像在Ruby On Rails中一樣3? – 2011-04-20 14:39:56

+0

據我所知,我必須爲每個實體編寫額外的方法才能獲得有限的結果? 順便說一句,這是什麼意思:@username? – 2011-04-20 14:41:24

+0

@ user717336我沒有說它在java中是不可能的(就像Sean指出的那樣),關鍵是最好在sql中這樣做,而不是加載所有數據並在代碼中進行過濾。關於你的第二個問題 - ':username',它只是一個參數,就像在命名查詢(http://www.javabeat.net/tips/108-how-use-named-parameters-and-named-query-i)中一樣。 html) – 2011-04-20 14:44:35