日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(3) Hibernate的查询 标准(Criteria)查询

發布時間:2024/1/23 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (3) Hibernate的查询 标准(Criteria)查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Hibernate的查詢 標準(Criteria)查詢

1 一個簡單例子:

Java代碼??

?@SuppressWarnings("unchecked")

public void searchByPropertys() {

Session session = this.getSession();

Criteria crit = session.createCriteria(Conft.class);

List<Conft> list = crit.list();

for(Conft c : list){

System.out.println(c.getId());

}

}

標準查詢API最終仍然翻譯為SQL交由數據庫處理,返回java.util.List對象

?

怎么增加條件呢?請看如下代碼:

Java代碼??

public void searchByPropertys() {

Session session = this.getSession();

Criteria crit = session.createCriteria(Conft.class);

crit.add(Restrictions.eq("id", 2)); // =

crit.add(Restrictions.ne("id", 2)); // !=

crit.add(Restrictions.lt("id", 2)); // <

crit.add(Restrictions.gt("id", 2)); // >

crit.add(Restrictions.le("id", 2)); // <=

crit.add(Restrictions.ge("id", 2)); // >=

crit.add(Restrictions.in("id", new String[]{"2"})); // in

crit.add(Restrictions.like("id", "%2%")); // like

crit.add(Restrictions.like("id", "2",MatchMode.ANYWHERE)); // %x%

crit.add(Restrictions.like("id", "2",MatchMode.START)); // x%

crit.add(Restrictions.like("id", "2",MatchMode.END)); // %x

crit.add(Restrictions.like("id", "2",MatchMode.EXACT)); // x

List<Conft> list = crit.list();

for(Conft c : list){

System.out.println(c.getId());

}

}?

代碼后面寫出了增加條件的方式和意思。

?

如果有and或者是or的關系的話,可以使用Conjunction(AND)和Disjunction(OR)!

下面是一個使用示例:

Java代碼??

public void searchByPropertys() {

Session session = this.getSession();

Criteria crit = session.createCriteria(Conft.class);

// 創建條件

Criterion a = Restrictions.gt("id", 2); // >

Criterion b = Restrictions.lt("id", 2); // <

Criterion c = Restrictions.like("id", "2",MatchMode.ANYWHERE);

// and 關系

Conjunction conjunction = Restrictions.conjunction();

conjunction.add(a);

conjunction.add(b);

// or 關系

Disjunction disjunction = Restrictions.disjunction();

disjunction.add(conjunction);

disjunction.add(c);

// 增加查詢條件

crit.add(disjunction);

List<Conft> list = crit.list();

for(Conft conft : list){

System.out.println(conft.getId());

}

}?

a和b是AND關系,而a和b合起來作為條件后和c是OR關系!

如果看他的SQL的話,是這樣的,有助于理解:

Java代碼??

(where (a>? and b<?) or c like ?)

除此之外還可以使用sqlRestriction方法直接拼接SQL

Java代碼??

?public User getUserById(int pk){

Session session = this.getSession();

Criteria crit = session.createCriteria(User.class);

crit.add(Restrictions.sqlRestriction(" {alias}.id=2 "));

List<User> list = crit.list();

return (User)list.get(0);

}

?

注意{alias}是表的名稱,這個不用修改,Hibernate在生成SQL時會自動替換!

在源碼中可以看到:

Java代碼??

public static Criterion sqlRestriction(String sql, Object values[], Type types[])

{

????return new SQLCriterion(sql, values, types);

}

public static Criterion sqlRestriction(String sql, Object value, Type type)

{

????return new SQLCriterion(sql, new Object[] {

????????value

????}, new Type[] {

????????type

????});

}

public static Criterion sqlRestriction(String sql)

{

????return new SQLCriterion(sql, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY);

}?

也就是說這個方法有三個調用方式,直接寫SQL,如果你的SQL中有 ? 作為占位符,那么可設置后面兩個參數,第二個參數對應 ? ,第三個是參數字段的類型!

如果有多個 ? ,那么第二和第三個參數就要用數組的形式來傳遞!

?

?


2 ?限制結果集內容
一個單獨的查詢條件是org.hibernate.criterion.Criterion?接口的一個實例。org.hibernate.criterion.Restrictions類?定義了獲得某些內置Criterion類型的工廠方法。?

List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.like("name",?"Fritz%")?)
???.add(?Restrictions.between("weight",?minWeight,?maxWeight)?)
???.list();
約束可以按邏輯分組。?

List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.like("name",?"Fritz%")?)
???.add(?Restrictions.or(
???????Restrictions.eq(?"age",?new?Integer(0)?),
???????Restrictions.isNull("age")
???)?)
???.list();
List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.in(?"name",?new?String[]?{?"Fritz",?"Izi",?"Pk"?}?)?)
???.add(?Restrictions.disjunction()
???????.add(?Restrictions.isNull("age")?)
?????.add(?Restrictions.eq("age",?new?Integer(0)?)?)
?????.add(?Restrictions.eq("age",?new?Integer(1)?)?)
?????.add(?Restrictions.eq("age",?new?Integer(2)?)?)
???)?)
???.list();
Hibernate提供了相當多的內置criterion類型(Restrictions?子類),?但是尤其有用的是可以允許你直接使用SQL。?

List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.sqlRestriction("lower({alias}.name)?like?lower(?)",?"Fritz%",?Hibernate.STRING)?)
???.list();
{alias}占位符應當被替換為被查詢實體的列別名。?

Property實例是獲得一個條件的另外一種途徑。你可以通過調用Property.forName()?創建一個Property。?

Property?age?=?Property.forName("age");
List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.disjunction()
???????.add(?age.isNull()?)
?????.add(?age.eq(?new?Integer(0)?)?)
?????.add(?age.eq(?new?Integer(1)?)?)
?????.add(?age.eq(?new?Integer(2)?)?)
???)?)
???.add(?Property.forName("name").in(?new?String[]?{?"Fritz",?"Izi",?"Pk"?}?)?)
???.list();
3 結果集排序
你可以使用org.hibernate.criterion.Order來為查詢結果排序。?

List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.like("name",?"F%")
???.addOrder(?Order.asc("name")?)
???.addOrder(?Order.desc("age")?)
???.setMaxResults(50)
???.list();
List?cats?=?sess.createCriteria(Cat.class)
???.add(?Property.forName("name").like("F%")?)
???.addOrder(?Property.forName("name").asc()?)
???.addOrder(?Property.forName("age").desc()?)
???.setMaxResults(50)
???.list();
4 關聯
你可以使用createCriteria()非常容易的在互相關聯的實體間建立?約束。?

List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.like("name",?"F%")?)
???.createCriteria("kittens")
???????.add(?Restrictions.like("name",?"F%")?)
???.list();
注意第二個?createCriteria()返回一個新的?Criteria實例,該實例引用kittens?集合中的元素。?

接下來,替換形態在某些情況下也是很有用的。?

List?cats?=?sess.createCriteria(Cat.class)
???.createAlias("kittens",?"kt")
???.createAlias("mate",?"mt")
???.add(?Restrictions.eqProperty("kt.name",?"mt.name")?)
???.list();
(createAlias()并不創建一個新的?Criteria實例。)?

Cat實例所保存的之前兩次查詢所返回的kittens集合是?沒有被條件預過濾的。如果你希望只獲得符合條件的kittens,?你必須使用ResultTransformer。?

List?cats?=?sess.createCriteria(Cat.class)
???.createCriteria("kittens",?"kt")
???????.add(?Restrictions.eq("name",?"F%")?)
???.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
???.list();
Iterator?iter?=?cats.iterator();
while?(?iter.hasNext()?)?{
???Map?map?=?(Map)?iter.next();
???Cat?cat?=?(Cat)?map.get(Criteria.ROOT_ALIAS);
???Cat?kitten?=?(Cat)?map.get("kt");
}
5 ?動態關聯抓取
你可以使用setFetchMode()在運行時定義動態關聯抓取的語義。?

List?cats?=?sess.createCriteria(Cat.class)
???.add(?Restrictions.like("name",?"Fritz%")?)
???.setFetchMode("mate",?FetchMode.EAGER)
???.setFetchMode("kittens",?FetchMode.EAGER)
???.list();
這個查詢可以通過外連接抓取mate和kittens。?查看第?19.1?節?“?抓取策略(Fetching?strategies)?”可以獲得更多信息。?

6 查詢示例
org.hibernate.criterion.Example類允許你通過一個給定實例?構建一個條件查詢。?

Cat?cat?=?new?Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List?results?=?session.createCriteria(Cat.class)
???.add(?Example.create(cat)?)
???.list();
版本屬性、標識符和關聯被忽略。默認情況下值為null的屬性將被排除。?

你可以自行調整Example使之更實用。?

Example?example?=?Example.create(cat)
???.excludeZeroes()???????????//exclude?zero?valued?properties
???.excludeProperty("color")??//exclude?the?property?named?"color"
???.ignoreCase()??????????????//perform?case?insensitive?string?comparisons
???.enableLike();?????????????//use?like?for?string?comparisons
List?results?=?session.createCriteria(Cat.class)
???.add(example)
???.list();
你甚至可以使用examples在關聯對象上放置條件。?

List?results?=?session.createCriteria(Cat.class)
???.add(?Example.create(cat)?)
???.createCriteria("mate")
???????.add(?Example.create(?cat.getMate()?)?)
???.list();
7 投影(Projections)、聚合(aggregation)和分組(grouping)
org.hibernate.criterion.Projections是?Projection?的實例工廠。我們通過調用?setProjection()應用投影到一個查詢。?

List?results?=?session.createCriteria(Cat.class)
???.setProjection(?Projections.rowCount()?)
???.add(?Restrictions.eq("color",?Color.BLACK)?)
???.list();
List?results?=?session.createCriteria(Cat.class)
???.setProjection(?Projections.projectionList()
???????.add(?Projections.rowCount()?)
???????.add(?Projections.avg("weight")?)
???????.add(?Projections.max("weight")?)
???????.add(?Projections.groupProperty("color")?)
???)
???.list();
在一個條件查詢中沒有必要顯式的使用?"group?by"?。某些投影類型就是被定義為?分組投影,他們也出現在SQL的group?by子句中。?

你可以選擇把一個別名指派給一個投影,這樣可以使投影值被約束或排序所引用。下面是兩種不同的實現方式:?

List?results?=?session.createCriteria(Cat.class)
???.setProjection(?Projections.alias(?Projections.groupProperty("color"),?"colr"?)?)
???.addOrder(?Order.asc("colr")?)
???.list();
List?results?=?session.createCriteria(Cat.class)
???.setProjection(?Projections.groupProperty("color").as("colr")?)
???.addOrder(?Order.asc("colr")?)
???.list();
alias()和as()方法簡便的將一個投影實例包裝到另外一個?別名的Projection實例中。簡而言之,當你添加一個投影到一個投影列表中時?你可以為它指定一個別名:?

List?results?=?session.createCriteria(Cat.class)
???.setProjection(?Projections.projectionList()
???????.add(?Projections.rowCount(),?"catCountByColor"?)
???????.add(?Projections.avg("weight"),?"avgWeight"?)
???????.add(?Projections.max("weight"),?"maxWeight"?)
???????.add(?Projections.groupProperty("color"),?"color"?)
???)
???.addOrder(?Order.desc("catCountByColor")?)
???.addOrder(?Order.desc("avgWeight")?)
???.list();
List?results?=?session.createCriteria(Domestic.class,?"cat")
???.createAlias("kittens",?"kit")
???.setProjection(?Projections.projectionList()
???????.add(?Projections.property("cat.name"),?"catName"?)
???????.add(?Projections.property("kit.name"),?"kitName"?)
???)
???.addOrder(?Order.asc("catName")?)
???.addOrder(?Order.asc("kitName")?)
???.list();
你也可以使用Property.forName()來表示投影:?

List?results?=?session.createCriteria(Cat.class)
???.setProjection(?Property.forName("name")?)
???.add(?Property.forName("color").eq(Color.BLACK)?)
???.list();
List?results?=?session.createCriteria(Cat.class)
???.setProjection(?Projections.projectionList()
???????.add(?Projections.rowCount().as("catCountByColor")?)
???????.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();
8 離線(detached)查詢和子查詢
DetachedCriteria類使你在一個session范圍之外創建一個查詢,并且可以使用任意的?Session來執行它。?

DetachedCriteria?query?=?DetachedCriteria.forClass(Cat.class)
???.add(?Property.forName("sex").eq('F')?);
???
Session?session?=?....;
Transaction?txn?=?session.beginTransaction();
List?results?=?query.getExecutableCriteria(session).setMaxResults(100).list();
txn.commit();
session.close();
DetachedCriteria也可以用以表示子查詢。條件實例包含子查詢可以通過?Subqueries或者Property獲得。?

DetachedCriteria?avgWeight?=?DetachedCriteria.forClass(Cat.class)
??.setProjection(?Property.forName("weight").avg()?);
session.createCriteria(Cat.class)
??.add(?Property.forName("weight).gt(avgWeight)?)
??.list();
DetachedCriteria?weights?=?DetachedCriteria.forClass(Cat.class)
??.setProjection(?Property.forName("weight")?);
session.createCriteria(Cat.class)
??.add(?Subqueries.geAll("weight",?weights)?)
??.list();
甚至相互關聯的子查詢也是有可能的:?

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();
9 根據自然標識查詢(Queries?by?natural?identifier)
對大多數查詢,包括條件查詢而言,因為查詢緩存的失效(invalidation)發生得太頻繁,查詢緩存不是非常高效。然而,有一種特別的查詢,可以通過不變的自然鍵優化緩存的失效算法。在某些應用中,這種類型的查詢比較常見。條件查詢API對這種用例提供了特別規約。?

首先,你應該對你的entity使用<natural-id>來映射自然鍵,然后打開第二級緩存。?

<class?name="User">
???<cache?usage="read-write"/>
???<id?name="id">
???????<generator?class="increment"/>
???</id>
???<natural-id>
???????<property?name="name"/>
???????<property?name="org"/>
???</natural-id>
???<property?name="password"/>
</class>
注意,此功能對具有mutable自然鍵的entity并不適用。?

然后,打開Hibernate?查詢緩存。?

現在,我們可以用Restrictions.naturalId()來使用更加高效的緩存算法。?

session.createCriteria(User.class)
???.add(?Restrictions.naturalId()
???????.set("name",?"gavin")
???????.set("org",?"hb")?
???).setCacheable(true)
???.uniqueResult();

?

總結

以上是生活随笔為你收集整理的(3) Hibernate的查询 标准(Criteria)查询的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。