电竞比分网-中国电竞赛事及体育赛事平台

分享

DetachedCriteria類詳解——hibernate

 一本正經(jīng)地胡鬧 2019-07-11

首先看DetachedCriteria這個類名,是由兩個單詞(detached和criteria)組成的,Criteria咱們知道是QBC查詢主要接口之一,它通過組裝各種Criterion對象來獲取實體,Hibernate中的Session是產(chǎn)生Criteria的工廠,Criterion實例一般來說都是通過Restrictions類獲取的,如下面這個例子:

List cats = session.createCriteria(Cat.class)

    .add( Restrictions.like("name", "Iz%") )

    .add( Restrictions.gt( "weight", new Float(minWeight) ) )

    .addOrder( Order.asc("age") )

    .list();

通過上述例子可以發(fā)現(xiàn)需要使用Session實例來獲取Criteria對象,再看另外一個單詞detached,意思為“分離的、分開的、分割的、未綁定依附的”意思,那到底跟誰分離、分開呢?對,就是session,也就是說兩個單詞合起來的意思是該類除了創(chuàng)建時不在依附于任何Session,但可以完整支持Criteria的功能,這就是DetachedCriteria的誕生的根本需求;

下面咱們再來討論下該類的應(yīng)用場景:

在常規(guī)的Web編程中,有大量的動態(tài)條件查詢,即用戶在網(wǎng)頁上面根據(jù)自身需要選擇錄入某些條件,程序根據(jù)用戶選擇內(nèi)容,動態(tài)生成查詢SQL語句,進行查詢。

  針對這種需求,對于分層應(yīng)用程序來說,Web層需要傳遞一個包含了查詢的條件條件的列表給業(yè)務(wù)層對象(傳統(tǒng)上使用Map對象),業(yè)務(wù)層對象獲得這個條件列表之后,依次從列表取出條件,構(gòu)造查詢語句。這里的一個難點是條件列表用什么來構(gòu)造?那么這么做的缺陷就是Map對象可以傳遞的信息非常有限,只能傳遞name和value,無法傳遞究竟要做怎樣的條件運算,即這么name和value之間什么關(guān)系,是>,<,IN,AND,OR呢?這就要求業(yè)務(wù)層對象必須確切掌握每條entry的隱含條件。因此一旦隱含條件改變,業(yè)務(wù)層對象的查詢構(gòu)造算法必須相應(yīng)修改,但是這種查詢條件的改變是隱式約定的,而不是程序代碼約束的,因此非常容易出錯。DetachedCriteria的出現(xiàn)解決了上述問題;

下面介紹一下DetachedCriteria的日常使用;

1、DetachedCriteria類允許你在Hibernate的Session范圍外創(chuàng)建一個查詢,然后使用任意一個Session環(huán)境去執(zhí)行它,這種用法也是使用最多的用法,該類提供了如下兩個方法用以構(gòu)建DetachedCriteria對象


代碼如下:

// 創(chuàng)建DetachedCriteria對象

DetachedCriteria query = DetachedCriteria.forClass(Cat.class).add( Property.forName("sex").eq('F') );

// 獲取Session對象

Session session = ....;

// 開啟事務(wù)

Transaction txn = session.beginTransaction();

// 將DetachedCriteria查詢對象與可執(zhí)行的Criteria實例關(guān)聯(lián)起來

List results = query.getExecutableCriteria(session).setMaxResults(100).list();

// 提交事務(wù)

txn.commit();

// 關(guān)閉Session,釋放資源

session.close();

2、一個DetachedCriteria可用作子查詢,Criterion實例可以通過Subqueries和Property類調(diào)用DetachedCriteria構(gòu)建的子查詢,如下代碼所示:

// 構(gòu)建所有Cat中的平均體重

DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)

    .setProjection(Property.forName("weight").avg());

// 獲取所有Cat中,高于平均提供的Cat的集合

session.createCriteria(Cat.class).add(Property.forName("weight").gt(avgWeight))

    .list();

// 構(gòu)建所有Cat的提供集合列表

DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)

    .setProjection(Property.forName("weight"));

// 獲取所有Cat中,體重最大的Cat

session.createCriteria(Cat.class).add(Subqueries.geAll("weight", weights))

    .list();

}

關(guān)聯(lián)子查詢,即DetachedCriteria構(gòu)建的子查詢和Criteria構(gòu)建的查詢也可以直接交互,如下:

DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")

.setProjection(Property.forName("weight").avg()).add(Property.forName("cat2.sex").eqProperty(

"cat.sex"));

session.createCriteria(Cat.class,"cat").add(Property.forName("weight").gt(avgWeightForSex)).list();

最后在上一個當(dāng)用DetachedCriteria構(gòu)建的投影,有多個列的例子:

DetachedCriteria sizeQuery = DetachedCriteria

.forClass(SlEmployee.class).setProjection(Projections.projectionList()

.add(Projections.property("userName"))

.add(Projections.property("employeeName")))

.add(Restrictions.eq("userName", "CHENGYU"));

List list = session.createCriteria(SlEmployee.class)

.add(Subqueries.propertiesEq(new String[] { "userName", "employeeName" }, sizeQuery)).list();

實際項目中用的最多的是第一種用法,即用來構(gòu)建一個查詢對象,對于子查詢這種用法則用的較少,通過例子可以看出,子查詢的功能似乎才更能體現(xiàn)出DetachedCriteria的強大?。?/p>


轉(zhuǎn)自:https://blog.csdn.net/yu102655/article/details/52469180 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多