問題九、Hibernate裡面如何用Criteria 查詢記錄數
【問題描述】在工作中,有一個比較複雜的feature使用的是hibernate的Criteria實現的查詢,但是PM要求在查詢資料前,先告知使用者有多少條資料,讓使用者去選擇返回多少條記錄。
【解決辦法】使用Projections.count(“property”) 或者 Projections.rowCount()
Criteria c = session.createCriteria(User.class);
c.setProjection(Projections.rowCount());
int rows=Integer.parseInt(c.uniqueResult().toString());
s.setProjection(null)
參考:http://blog.csdn.net/virgoboy…
問題十、Hibernate Criteria Join with 3 Tables
Criteria c = session.createCriteria(Dokument.class, "dokument");
c.createAlias("dokument.role", "role"); // inner join by default
c.createAlias("role.contact", "contact");
c.add(Restrictions.eq("contact.lastName", "Test"));
return c.list();
或者這樣:
Criteria c = session.createCriteria(Dokument.class);
c.createAlias("role", "role"); // inner join by default
c.createAlias("role.contact", "contact");
c.add(Restrictions.eq("contact.lastName", "Test"));
return c.list();
如果實體物件中含有OneToMany關聯物件的情況,既是實體中含有list或Set等關聯實體集合的情況下怎麼辦呢?
這個還不知道怎麼辦,呵呵
方法其實是非常簡單的:
dc.createAlias("tags", "t");
dc.add(Restrictions.eq("t.id", tagId));
其中tags是個Set,但是想查詢屬性tags中含有id為tagId的實體,使用上面的就可以了。
這裡有一個特殊情況,如果是對引用物件的id查詢,則可以不用建立引用,也就是可以不呼叫createAlias()語句
,如下所示:
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.add(Restrictions.like("team.id", teamId, MatchMode.ANYWHERE));
據我個人的經驗,team後只能跟其主鍵屬性,比較其他屬性要用別名。
參考:http://stackoverflow.com/ques…
http://www.cnblogs.com/newpan…
問題十一、DetachedCriteria、Criteria 使用區別
在常規的Web程式設計中,有大量的動態條件查詢,即使用者在網頁上面自由選擇某些條件,程式根據使用者的選擇條件,動態生成SQL語句,進行查詢。
此時,我們不能在Web層使用Criteria,因為它是和Session繫結的。
DetachedCriteria可以解決這個問題,即在web層,程式設計師使用DetachedCriteria來構造查詢條件,然後將這個 DetachedCriteria作為方法呼叫引數傳遞給業務層物件。而業務層物件獲得DetachedCriteria之後,可以在session範圍內直接構造Criteria,進行查詢。就此,查詢語句的構造完全被搬離到web層實現,而業務層則只負責完成持久化和查詢的封裝即可,與查詢條件構造完全解耦,非常完美!
Criteria 和 DetachedCriteria 的主要區別
在於建立的形式不一樣, Criteria 是線上的,所以它是由 Hibernate Session 進行建立的,而 DetachedCriteria 是離線的,建立時無需Session .
DetachedCriteria的建立
DetachedCriteria 提供了 2 個靜態方法 ,進行DetachedCriteria 例項的建立。
forClass(Class)
forEntityName(Name)
Spring 的框架提供了對於離線查詢的支援,非常的簡單的使用那些方法
Spring 的框架提供了getHibernateTemplate().findByCriteria(detachedCriteria)
方法可以很方便地根據DetachedCriteria 來返回查詢結果。Criteria的子類就是 DetachedCriteria 我們可以簡單的使用就好了。
使用到了這些我們就不得不說 Restrictions 是產生查詢條件的工具類。
當然你也可以手動這麼幹:
DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
.add( Property.forName("sex").eq(`F`) );
//建立一個Session
Session session = .;
Transaction txn = session.beginTransaction();
List results = query.getExecutableCriteria(session).setMaxResults(100).list();
txn.commit();
session.close();
切記,DetachedCriteria例項不要去重用它
。
DetachedCriteria作為子查詢
//主查詢:人員查詢
DetachedCriteria searDc =
DetachedCriteria.forClass(QymlPerson.class);
//子查詢:職務人員關係表
DetachedCriteria sub =
DetachedCriteria.forClass(QymlPositionUserLink.class);
sub.add(Restrictions.eq("positionunid", positionunid));
//子查詢:指定查詢的列(也就是select usernuid from ....)
sub.setProjection(Property.forName("userunid"));
//主查詢和子查詢關聯(也就是where unid in (select userunid from...) )
searDc.add(Property.forName("unid").in(sub));
在上面的例子中,用個一個類似於下面SQL 的子查詢
Select * from Person a where a.unid in (select userunid from PositionUserLink b where
b.positionunid = ..)
Property 還有其他的條件判斷,參考api
http://docs.jboss.org/hiberna…
ion/Property.html。
動態關聯抓取
我們的抓取模式,對於1對多的關聯的形式!是不是抓取過來呢?
你可以使用setFetchMode()
在執行時定義動態關聯抓取的語義
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.JOIN)
.setFetchMode("kittens", FetchMode.JOIN)
.list();
這個查詢可以通過外連線抓取mate和kittens。
參考:http://blog.csdn.net/u0128819…
http://blog.sina.com.cn/s/blo…
問題十二、投影(Projections)、聚合(aggregation)和分組(grouping)
org.hibernate.criterion.Projections
是 Projection
的例項工廠。
我們通過呼叫setProjection()應用投影到一個查詢。這個的意思就是查詢哪一列的意思
用來進行聚合操作,和sql中的聚合類似.求和/求平均值/統計記錄數/…等等.
還有用來獲取獲取物件的某些屬性(表欄位)或屬性集合.正常情況下,查詢返回的是物件或物件的集合.使用投影的話就可以只返回你需要的屬性值.此時,即Hibernate不把記錄封裝物件了,只返回你在投影中設定的屬性的值(值的集合)的陣列
List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount() )
//當你新增一個投影到一個投影列表中時 你可以為它指定一個別名:如
//.add( Projections.rowCount() ,"count")
.add( Projections.avg("weight") )
.add( Projections.max("weight") )
.add( Projections.groupProperty("color") )
)
.list();
可以選擇把一個別名指派給一個投影,這樣可以使投影值被約束或排序所引用。下面是兩種不同的實現方式:
List results = session.createCriteria(Cat.class)
.setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
//.setProjection( Projections.groupProperty("color").as("colr") )
.addOrder( Order.asc("colr") )
.list();
也可以使用Property.forName()
來表示投影:
List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount().as("catCountByColor") )
.add( Property.forName("name"))
.add( Property.forName("weight").avg().as("avgWeight") )
.add( Property.forName("weight").max().as("maxWeight") )
.add( Property.forName("color").group().as("color" )
)
.addOrder( Order.desc("catCountByColor") )
.addOrder( Order.desc("avgWeight") )
.list();