2013-10-29 43 views
4

我嘗試使用Hibernate分頁我的查詢(PostgreSQL的)休眠分頁機制

我設置setFirstResult(0),setMaxResults(20)我的SQL查詢。我的代碼如下圖所示:

Session session = getSessionFactory().getCurrentSession(); 
session.beginTransaction(); 
Query query = session.createQuery("FROM Customers"); 
query.setFirstResult(0); 
query.setMaxResults(20); 
List<T> entities = query.list(); 
session.getTransaction().commit(); 

但查看SQL休眠日誌的時候,我仍然看到完整的SQL查詢:

Hibernate: select customer0_.id as id9_, customer0_.customer_name as dst2_9_, customer0_.addres as dst3_9_ from tbl_customers customer0_ 

爲什麼沒有限制在Hibernate中的分頁SQL日誌查詢OFFSET?

有沒有人知道關於Hibernate分頁機制?

我想Hibernate會選擇所有數據,將數據放入Resultset,然後在Resultset中分頁,對不對?

+0

不Hibernate Hibernate不這樣做,它試圖在查詢級應用分頁。我相信這是一個方言問題,你確定你已經在Hibernate配置中設置了Postgre方言嗎? –

+0

順便問一下,這是SQL還是HQL?您必須將HQL傳遞給'createQuery'方法。 –

+0

在這個例子中,我正在使用:Hibernate查詢示例(HQL) – MartinJoo

回答

4

我在查詢和hibernate回調中使用。兩者都按預期工作。 Hibernate Query針對給定的First和Max大小之間的結果執行。這裏看起來像你傳遞了SQL而不是HQL來查詢。如果是的話,它不應該工作。

- 在此處查看我的代碼。

 Query query = this.getSession().createQuery("FROM QueryType"); 
     query.setFirstResult(0); 
     query.setMaxResults(20); 
     List toDelete = query.list(); 

,並在日誌中:

從 選擇 * (選擇 - 所有列名(不想在這裏分享) 從 MY_TBL_NAME querytype0_。) 其中 ROWNUM < = ?

+0

我正在使用Hibernate查詢示例(HQL)(我更新了我的代碼),而不是Native SQL。它仍然顯示日誌查詢全部。 – MartinJoo

6

有很多方法可以分頁。

HQL和setFirstResult,setMaxResults API

Session session = sessionFactory.openSession(); 
Query query = session.createQuery("From Foo"); 
query.setFirstResult(0); 
query.setMaxResults(10); 
List<Foo> fooList = query.list(); 
//Total count 
String countQ = "Select count (f.id) from Foo f"; 
Query countQuery = session.createQuery(countQ); 
Long countResults = (Long) countQuery.uniqueResult(); 
//Last Page 
int pageSize = 10; 
int lastPageNumber = (int) ((countResult/pageSize) + 1); 

HQL和的ScrollableResults API

String hql = "FROM Foo f order by f.name"; 
Query query = session.createQuery(hql); 
int pageSize = 10; 

ScrollableResults resultScroll = query.scroll(ScrollMode.FORWARD_ONLY); 
resultScroll.first(); 
resultScroll.scroll(0); 
List<Foo> fooPage = Lists.newArrayList(); 
int i = 0; 
while (pageSize > i++) { 
    fooPage.add((Foo) resultScroll.get(0)); 
    if (!resultScroll.next()) 
     break; 
} 
//Total count 
resultScroll.last(); 
int totalResults = resultScroll.getRowNumber() + 1; 

簡單的標準API

Criteria criteria = session.createCriteria(Foo.class); 
criteria.setFirstResult(0); 
criteria.setMaxResults(pageSize); 
List<Foo> firstPage = criteria.list(); 
//Total count 
Criteria criteriaCount = session.createCriteria(Foo.class); 
criteriaCount.setProjection(Projections.rowCount()); 
Long count = (Long) criteriaCount.uniqueResult(); 

baeldung列舉了所有的例子。

+0

您使用ScrollableResults API的示例會將內容讀入內存。 [見這裏](http://stackoverflow.com/questions/2826319/using-hibernates-scrollableresults-to-slowly-read-90-million-records)。您可以按照@Sean S.的解釋使其工作,但它絕對不提供簡單的解決方案。 – thisismydesign

+0

RDBMS依賴和**不**所有RDBMS都有這個問題。很高興知道,但這不是原來的海報問題/關注 –