Hibernate之?dāng)?shù)據(jù)檢索- -
數(shù)據(jù)檢索
數(shù)據(jù)查詢與檢索是Hibernate中的一個(gè)亮點(diǎn)。相對(duì)其他ORM實(shí)現(xiàn)而言,Hibernate提供了靈活多樣的查詢機(jī)制。其中包括: 1. Criteria Query 2. Hibernate Query Language (HQL) 3. SQL Criteria Query Criteria Query通過(guò)面向?qū)ο蠡脑O(shè)計(jì),將數(shù)據(jù)查詢條件封裝為一個(gè)對(duì)象。簡(jiǎn)單來(lái)講,Criteria Query可以看作是傳統(tǒng)SQL的對(duì)象化表示,如: Criteria criteria = session.createCriteria(TUser.class); criteria.add(Expression.eq("name","Erica")); criteria.add(Expression.eq("sex",new Integer(1))); 這里的criteria 實(shí)例實(shí)際上是SQL “Select * from t_user where name=’Erica’ and sex=1”的封裝(我們可以打開(kāi)Hibernate 的show_sql 選項(xiàng), 以觀察Hibernate在運(yùn)行期生成的SQL語(yǔ)句)。 Hibernate 在運(yùn)行期會(huì)根據(jù)Criteria 中指定的查詢條件(也就是上面代碼中通過(guò)criteria.add方法添加的查詢表達(dá)式)生成相應(yīng)的SQL語(yǔ)句。 這種方式的特點(diǎn)是比較符合Java 程序員的編碼習(xí)慣,并且具備清晰的可讀性。正因?yàn)榇?,不少ORM實(shí)現(xiàn)中都提供了類似的實(shí)現(xiàn)機(jī)制(如Apache OJB)。 對(duì)于Hibernate的初學(xué)者,特別是對(duì)SQL了解有限的程序員而言,Criteria Query無(wú)疑是上手的極佳途徑,相對(duì)HQL,Criteria Query提供了更易于理解的查詢手段,借助IDE的Coding Assist機(jī)制,Criteria的使用幾乎不用太多的學(xué)習(xí)。 Criteria 查詢表達(dá)式 Criteria 本身只是一個(gè)查詢?nèi)萜?,具體的查詢條件需要通過(guò)Criteria.add方法添加到Criteria實(shí)例中。 如前例所示,Expression 對(duì)象具體描述了查詢條件。針對(duì)SQL 語(yǔ)法,Expression提供了對(duì)應(yīng)的查詢限定機(jī)制,包括: 方法 描述 Expression.eq 對(duì)應(yīng)SQL“field = value”表達(dá)式。 如Expression.eq("name","Erica") Expression.allEq 參數(shù)為一個(gè)Map對(duì)象,其中包含了多個(gè)屬性-值對(duì)應(yīng)關(guān)系。相當(dāng)于多個(gè)Expression.eq關(guān)系的疊加。 Expression.gt 對(duì)應(yīng)SQL中的 “field > value ” 表達(dá)式 Expression.ge 對(duì)應(yīng)SQL中的 “field >= value” 表達(dá)式 Expression.lt 對(duì)應(yīng)SQL中的 “field < value” 表達(dá)式 Expression.le 對(duì)應(yīng)SQL中的 “field <= value” 表達(dá)式 Expression.between 對(duì)應(yīng)SQL中的 “between” 表達(dá)式 如下面的表達(dá)式表示年齡(age)位于13到50區(qū)間內(nèi)。 Expression.between("age",new Integer(13),new Integer(50)); Expression.like 對(duì)應(yīng)SQL中的 “field like value” 表達(dá)式 Expression.in 對(duì)應(yīng)SQL中的 ”field in …” 表達(dá)式 Expression.eqProperty 用于比較兩個(gè)屬性之間的值,對(duì)應(yīng)SQL中的“field= field”。 如: Expression.eqProperty("TUser.groupID","TGroup.id"); Expression.gtProperty 用于比較兩個(gè)屬性之間的值,對(duì)應(yīng)SQL中的“field > field”。 Expression.geProperty 用于比較兩個(gè)屬性之間的值,對(duì)應(yīng)SQL中的“field >= field”。 Expression.ltProperty 用于比較兩個(gè)屬性之間的值,對(duì)應(yīng)SQL中的“field < field”。 Expression.leProperty 用于比較兩個(gè)屬性之間的值,對(duì)應(yīng)SQL中的“field <= field”。 Expression.and and關(guān)系組合。 如: Expression.and( Expression.eq("name","Erica"), Expression.eq( "sex", new Integer(1) ) ); Expression.or or關(guān)系組合。 如: Expression.or( Expression.eq("name","Erica"), Expression.eq("name","Emma") ); Expression.sql 作為補(bǔ)充,本方法提供了原生SQL語(yǔ)法的支持。我 們可以通過(guò)這個(gè)方法直接通過(guò)SQL語(yǔ)句限定查詢 條件。 下面的代碼返回所有名稱以“Erica”起始的記錄: Expression.sql( “lower({alias}.name) like lower(?)”, "Erica%", Hibernate.STRING ); 其中的“{alias}”將由Hibernate在運(yùn)行期使 用當(dāng)前關(guān)聯(lián)的POJO別名替換。 注意Expression 各方法中的屬性名參數(shù)(如Express.eq中的第一個(gè)參數(shù)),這里所謂屬性名是POJO中對(duì)應(yīng)實(shí)際庫(kù)表字段的屬性名(大小寫(xiě)敏感),而非庫(kù)表中的實(shí) 際字段名稱。 Criteria 高級(jí)特性 限定返回的記錄范圍 通過(guò)criteria. setFirstResult/setMaxResults 方法可以限制一次查詢返回的記錄范圍: Criteria criteria = session.createCriteria(TUser.class); //限定查詢返回檢索結(jié)果中,從第一百條結(jié)果開(kāi)始的20條記錄 criteria.setFirstResult(100); criteria.setMaxResults(20); 對(duì)查詢結(jié)果進(jìn)行排序 //查詢所有g(shù)roupId=2的記錄 //并分別按照姓名(順序)和groupId(逆序)排序 Criteria criteria = session.createCriteria(TUser.class); criteria.add(Expression.eq("groupId",new Integer(2))); criteria.addOrder(Order.asc("name")); criteria.addOrder(Order.desc("groupId")); Criteria作為一種對(duì)象化的查詢封裝模式,不過(guò)由于Hibernate在實(shí)現(xiàn)過(guò)程中將精力 更加集中在HQL查詢語(yǔ)言上,因此Criteria的功能實(shí)現(xiàn)還沒(méi)做到盡善盡美(這點(diǎn)上,OJB 的Criteria 實(shí)現(xiàn)倒是值得借鑒),因此,在實(shí)際開(kāi)發(fā)中,建議還是采用Hibernate 官 方推薦的查詢封裝模式:HQL。 Hibernate Query Language (HQL) Criteria提供了更加符合面向?qū)ο缶幊棠J降牟樵兎庋b模式。不過(guò),HQL(Hibernate Query Language)提供了更加強(qiáng)大的功能,在官方開(kāi)發(fā)手冊(cè)中,也將HQL作為推薦的查詢 模式。 相對(duì)Criteria,HQL提供了更接近傳統(tǒng)SQL語(yǔ)句的查詢語(yǔ)法,也提供了更全面的特性。 最簡(jiǎn)單的一個(gè)例子: String hql = "from org.hibernate.sample.TUser"; Query query = session.createQuery(hql); List userList = query.list(); 上面的代碼將取出TUser的所有對(duì)應(yīng)記錄。 如果我們需要取出名為“Erica”的用戶的記錄,類似SQL,我們可以通過(guò)SQL 語(yǔ)句加 以限定: String hql = "from org.hibernate.sample.TUser as user where user.name=‘Erica‘"; Query query = session.createQuery(hql); List userList = query.list(); 其中我們新引入了兩個(gè)子句“as”和“where”,as子句為類名創(chuàng)建了一個(gè)別名,而where 子句指定了限定條件。 HQL 子句本身大小寫(xiě)無(wú)關(guān),但是其中出現(xiàn)的類名和屬性名必須注意大小寫(xiě)區(qū)分。 關(guān)于HQL,Hibernate 官方開(kāi)發(fā)手冊(cè)中已經(jīng)提供了極其詳盡的說(shuō)明和示例,詳見(jiàn) Hibernate官方開(kāi)發(fā)手冊(cè)(Chapter 11)。 |
|
來(lái)自: shaobin0604@1... > 《Java》