總結DetachedCriteria級聯查…

zhengdesheng19930211發表於2017-03-21

如果實體物件中沒有關聯物件的情況使用DetachedCriteria進行查詢是一件很簡單的事情。
如果實體物件中含有OneToOne或者ManyToOne關聯物件的情況可以參考下面方式,使用別名:
假設要通過stuName查詢一個學生Student記錄,可以如下:

Java程式碼
  1. DetachedCriteria dc = DetachedCriteria.forClass(Student.class);   
  2. dc.add(Restrictions.like("stuName", stuName, MatchMode.ANYWHERE));  
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.add(Restrictions.like("stuName", stuName, MatchMode.ANYWHERE));


    
如果要通過Student的Team的teamName查詢一個Student記錄,很多人都會這麼寫:

Java程式碼
  1. DetachedCriteria dc = DetachedCriteria.forClass(Student.class);   
  2. dc.add(Restrictions.like("team.teamName", teamName, MatchMode.ANYWHERE));  
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.add(Restrictions.like("team.teamName", teamName, MatchMode.ANYWHERE));


    
遺憾的是上述程式報錯,說是在Student中找不到team.teamName屬性,這是可以理解的。那麼如何通過teamName查詢Student呢?
可以這麼寫:

Java程式碼
  1. DetachedCriteria dc = DetachedCriteria.forClass(Student.class);   
  2. dc.createAlias("team", "t");   
  3. dc.add(Restrictions.like("t.teamName", teamName, MatchMode.ANYWHERE));  
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.createAlias("team", "t");
dc.add(Restrictions.like("t.teamName", teamName, MatchMode.ANYWHERE));


沒錯,就是要先建立team的引用,才能用team導航到teamName。

這裡有一個特殊情況,如果是對引用物件的id查詢,則可以不用建立引用,也就是可以不呼叫createAlias()語句,如下所示:

Java程式碼
  1. DetachedCriteria dc = DetachedCriteria.forClass(Student.class);   
  2. dc.add(Restrictions.like("team.id", teamId, MatchMode.ANYWHERE));  
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.add(Restrictions.like("team.id", teamId, MatchMode.ANYWHERE));


據我個人的經驗,team後只能跟其主鍵屬性,比較其他屬性要用別名。此主鍵屬性可以用“id”字元來指代,也可以用team的主鍵屬性來指代。換句話說,我的Student類的類主鍵“stuId”,不管是在HQL還是在QBC中,都可以用stu.id來指代stu.stuId。在這裡可以看出 “id”字元的特殊性。上述是個人觀點,並未得到確實的證實。

補充:
如果是三級或更多級查詢怎麼辦?

以三級查詢為例,仍引用上面的例子:

Java程式碼
  1. DetachedCriteria dc = DetachedCriteria.forClass(Student.class);   
  2. dc.createAlias("team", "t");   
  3. dc.createAlias("t.school", "s");   
  4. dc.add(Restrictions.like("s.schoolName", schoolName, MatchMode.ANYWHERE)); 


設定返回ROOT物件
 detachedCriteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);

相關文章