Java的Hibernate框架中Criteria查詢使用的例項講解

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

我們講一下Criteria查詢,這個對於不是太熟悉SQL語句的我們這些程式設計師來說是很容易上手的。
 廢話不多說,看一下例子:
 實體類如下:


public class User implements Serializable{ 
private static final long serialVersionUID = 1L; 
public Long id; 
private String name; 
private int age; 
//省略Get/Set方法 
} 

  對映檔案我們就不寫了,很簡單的一個實體,如果不懂的童鞋請參照我在hibernate分類中的其他文章。
 接下來我們看如何使用Criteria來進行查詢:
 


public static void main(String[] args) { 
Configuration cfg = new Configuration().configure(); 
SessionFactory sessionFactory = cfg.buildSessionFactory(); 
Session session = sessionFactory.openSession(); 
Criteria criteria = session.createCriteria(User.class); 
criteria.add(Restrictions.eq("name","shun")); 
List list = criteria.list(); 
Iterator iter = list.iterator(); 
while(iter.hasNext()) { 
User user = (User)iter.next(); 
System.out.println(user.getName() ":" user.getAge()); 
} 
session.close(); 
} 

  看到程式碼,很簡單的一串。
 前面都很熟悉啦,我們看到構造session之後的程式碼:
 


Criteria criteria = session.createCriteria(User.class); 
criteria.add(Restrictions.eq("name","shun")); 

  這兩句程式碼是重點,我們來分析一下,究竟是什麼意思?
 第一句我們通過session得到Criteria實現類的一個物件,接著第二句我們通過add方法新增一個條件,eq表示相等。在Hibernate3以前是通過Expression.eq來實現,3之後由於Criteria被拋棄,我們改用Restrictions類來實現,它和Expression一樣的用法。我們看看API發現Expression繼承於Restrictions。
 回到我們上面的兩句,我們做完這些工作後,實際上hibernate幫我們構造了類似


select * from user where name='shun' 

  這樣的語句。(這裡我們對映檔案中User類對應的表是user表,而name屬性對應的是name欄位)
 
 Restrictions還有許多幫助我們構造SQL語句的方法,大家查一下API很容易就可以理解了。
 
 我們重新看一下上面的程式碼,如果我們關閉了session,但是我們想繼續使用這個criteria,行嗎?我們來看一下。
 在上面的程式碼之後,我們重新遍歷,加上:
 


List list2 = criteria.list(); 
Iterator iter2 = list.iterator(); 
while(iter.hasNext()) { 
User user = (User)iter.next(); 
System.out.println(user.getName() ":" user.getAge()); 
} 

  為了區分跟上一個list和iter的區別,我們這裡用另外一個。
 執行它,我們得到的是一個異常:
 


org.hibernate.SessionException: Session is closed! 

  報這個異常表示session已經關閉,很多情況下我們在關閉了session再進行saveOrUpdate,save等跟持久化相關的操作都會報類似的異常。
 Hibernate3考慮到了我們這個需求,它實現了一個DetachedCriteria,這個可以獨立於Session而存在。
 我們來看一下例子:(實體還是上面的)
 


public static void main(String[] args) { 
Configuration cfg = new Configuration().configure(); 
SessionFactory sessionFactory = cfg.buildSessionFactory(); 
Session session = sessionFactory.openSession(); 
DetachedCriteria decriteria = DetachedCriteria.forClass(User.class); 
decriteria.add(Restrictions.eq("name","shun")); 
List list = decriteria.getExecutableCriteria(session).list(); 
Iterator iter = list.iterator(); 
while(iter.hasNext()) { 
User user = (User)iter.next(); 
System.out.println(user.getName() ":" user.getAge()); 
} 
session.close(); 
Session session2 = sessionFactory.openSession(); 
List list2 = decriteria.getExecutableCriteria(session2).list(); 
Iterator iter2 = list2.iterator(); 
while(iter2.hasNext()) { 
User user = (User)iter2.next(); 
System.out.println(user.getName() ":" user.getAge()); 
} 
} 

  我們看到在session關閉之後,我們在另外一個連線中還是可以繼續用DetachedCriteria。我們需要通過getExecutableCriteria(Session session)把當前的DetachedCriteria跟某一個Session進行關聯。
 
 
 接下來我們再來看一下Subqueries類與DetachedCriteria的結合使用:
 


public static void main(String[] args) { 
Configuration cfg = new Configuration().configure(); 
SessionFactory sessionFactory = cfg.buildSessionFactory(); 
Session session = sessionFactory.openSession(); 
DetachedCriteria decriteria = DetachedCriteria.forClass(User.class); 
decriteria.setProjection(Projections.avg("age")); 
Criteria criteria = session.createCriteria(User.class); 
criteria.add(Subqueries.propertyGt("age",decriteria)); 
List list = criteria.list(); 
Iterator iter = list.iterator(); 
while(iter.hasNext()) { 
User user = (User)iter.next(); 
System.out.println(user.getName() ":" user.getAge()); 
} 
session.close(); 
} 

  估計大家有疑問的應該是第一句程式碼:
 


decriteria.setProjection(Projections.avg("age")); 

  這句程式碼是指通過decriteria得到age的平均值。然後在下面取得大於平均值的age的物件。
 Projections包含了許多實現SQL方法的封裝方法,大家可以看一下API。

下面我們來了解一下它的稍微高階點的用法。
 直接看程式碼吧:


criteria.setFirstResult(10); 
criteria.setMaxResults(20); 

  這裡我們設定了開始的記錄是第10條,然後從第10條開始查出20條記錄,根據這個做法,我們就可以實現基本的分頁功能了。
 當然,我們在很多情況下都需要排序,criteria也是支援的:


criteria.addOrder(Order.desc("age")); 

  這裡,我們直接用addOrder方法即可,裡面通過Order.desc得到一個Order物件,它需要一個屬性引數。實際上當我們呼叫addOrder時,hibernate會幫我們生成order by age,這樣的語句。
 
 當我們需要進行分組時,這個怎麼做呢?這個就需要用到我們上次有涉及到的Projections這個類的groupProperty方法,
 


criteria.setProjection(Projections.groupProperty("age")); 

  這裡我們就根據age屬性來進行分組,實際上也就是通過age對應的欄位age進行分組,hibernate會自動幫我們轉換成group by age這樣的語句。
Projections中有許多實用的方法(注意,此為是hibernate 3後才有的)。  
 

您可能感興趣的文章:

springmvc4 hibernate4分頁查詢功能實現Java Hibernate中使用HQL語句進行資料庫查詢的要點解析全面解析Hibernate關聯操作、查詢操作、高階特性、併發處理機制Java的Hibernate框架資料庫操作中鎖的使用和查詢型別在Java的Hibernate框架中對資料庫資料進行查詢操作hibernate 命名查詢如何實現Hibernate 查詢方式總結Hibernate中的多表查詢及抓取策略

相關文章

程式語言 最新文章