第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Hibernate 中的 Criteria 查詢

1. 前言

今天給大家介紹一個(gè)絕對(duì)純正的 OOP 查詢方案:Criteria 查詢。通過本節(jié)課程的內(nèi)容,你將了解到:

  • 什么是 Criteria 查詢
  • Criteria 實(shí)現(xiàn)復(fù)雜查詢;

2. Criteria 查詢

什么是 Criteria 查詢?

Criteria 查詢從字面翻譯就是標(biāo)準(zhǔn)查詢。所謂 標(biāo)準(zhǔn)查詢,指的是 HIbernate 提供了純正的 OOP API 查詢方案。不像 HQL 還摻雜了一些 SQL 層面的內(nèi)容。

來一個(gè)查詢需求:查詢所有的學(xué)生。

想必這學(xué)生會(huì)很生氣,總是被搬來搬去的。

上實(shí)例之前,先認(rèn)識(shí) Hibernate 兄弟會(huì)中的一名新成員:Criteria

在使用 Criteria 查詢之前,必須先創(chuàng)建 Criteria 對(duì)象:

Criteria cr = session.createCriteria(Student.class);
List<Student> stus = cr.list();

是不是很 OOP。使用 HQL 時(shí),會(huì)有一種時(shí)空穿越的感覺 ,OOPSQL 語法交替出現(xiàn),很容易犯暈。使用 Criteria 進(jìn)行查詢時(shí)則不會(huì)。

而且,Criteria 不是一個(gè)人在戰(zhàn)斗,它也有屬于自己的兄弟會(huì),為開發(fā)者提供了更強(qiáng)有力的支持。

先介紹一下它的幾個(gè)兄弟,并且它們的作用已經(jīng)從字面告訴了你。

  • Criterion: 這位兄弟長得好生面熟,其實(shí)它就 Criteria 的單數(shù)存在形式;
  • Oder: 提供排序功能;
  • Restrictions: 限制、約束的意思,和 SQL 中的 where 關(guān)鍵字的作用是一樣。所以,它提供了很多類似于運(yùn)算符的方法,可以對(duì)查詢數(shù)據(jù)進(jìn)行過濾。

Criteria 面子上很 OOP ,但是無論你怎么逃,都是在 SQL 的手掌心,也就是說 Criteria 查詢最終還是會(huì)被 Hibernate 轉(zhuǎn)譯成 SQL 語句。

只要是使用關(guān)系型數(shù)據(jù)庫,SQL 就是逃不掉的宿命。只是直接、間接使用的區(qū)別。

所以,Criteria 查詢中總會(huì)找到 SQL 的影子。

2.1 基礎(chǔ)查詢

為了更好地理解它們,來一個(gè)實(shí)例:查詢姓名叫 “Hibernate” 的學(xué)生。

Criteria criteria = session.createCriteria(Student.class);
Criterion criterion = Restrictions.eq("stuName", "Hibernate");
criteria.add(criterion);
Student student = (Student) criteria.uniqueResult();
System.out.println(student);

Criteria 查詢封裝了關(guān)系型數(shù)據(jù)庫的概念,所以,一定要注意,使用方法進(jìn)行數(shù)據(jù)過濾時(shí),都是屬性進(jìn)行比較。

確認(rèn)查詢出來的數(shù)據(jù)只有一條記錄時(shí),可以使用 uniqueResult() 方法。條件查詢的關(guān)鍵是了解 Restrictions,它所提供的很多類似于邏輯運(yùn)算符的方法:

  • Restrictions.eq(): 相當(dāng)于 =;
  • Restrictions.not(Exprission.eq()) : 相當(dāng)于 <>;
  • Restrictions.le(): 相當(dāng)于 <=;
  • Restrictions.gt(): 相當(dāng)于 >;
  • Restrictions.ge(): 相當(dāng)于 >=;
  • Restrictions.lt(): 相當(dāng)于 <;
  • Restrictions.isnull(): 相當(dāng)于 is null;
  • Restrictions.isNotNull(): 相當(dāng)于 is not null ;
  • Restrictions.like(): 相當(dāng)于 like;
  • Restrictions.and(): 相當(dāng)于 and;
  • Restrictions.conjunction(): 相當(dāng)于 and;
  • Restrictions.or(): 相當(dāng)于 or;
  • Restrictions.disjunction() : 相當(dāng)于 or;
  • Restrictions.not(): 相當(dāng)于 not;
  • Restrictions.in(): 相當(dāng)于 in;
  • Restrictions.not(Restrictions.in()): 相當(dāng)于 not in;
  • Restrictions.between(): 相當(dāng)于 between x and y;
  • Restrictions.not(Restrictions…between()) : 相當(dāng)于 not between x and y。

如上方法,幾乎涵蓋了所有 SQL 條件運(yùn)算符,任意組合上面方法,沒有查詢不出來的結(jié)果。

如查詢學(xué)生編號(hào)是 1 或 2 或 4 的學(xué)生。
使用 SQL,則是:

select * from student where stuId in (1,2,4)

使用 Criteria 查詢,則如下所示:

Criterion criterion = Restrictions.in("stuId",new Integer[] {1,2,4} );
criteria.add(criterion);

如查詢學(xué)生編號(hào)大于 2 且班級(jí)編號(hào)為 1 的學(xué)生。

使用 SQL:

select * from student where stuId>2 and classRommId=1

如果使用 Criteria 查詢,則先構(gòu)建兩個(gè)約束對(duì)象:

Criterion criterion = Restrictions.gt("stuId", 2);
Criterion criterion1 = Restrictions.eqOrIsNull("classRoom.classRoomId", 1);

再把這兩個(gè)約束作為參數(shù),構(gòu)建一條聯(lián)合約束:

LogicalExpression logicalExpression = Restrictions.and(criterion, criterion1);
criteria.add(logicalExpression);

LogicalExpression API 用來表示一個(gè)邏輯表達(dá)式。是 Criterion 的子類。

比較原生 SQLCriteria 查詢,會(huì)發(fā)現(xiàn)原生 SQL 語句要簡(jiǎn)單很多,使用 Criteria 查詢需要掌握很多 API,而且代碼量也比較大,這也可能是 Criteria 查詢得不到普及的原因吧。

但是,Hibernate 既然推出了這種查詢方案,想必也有它的考慮。比如說,創(chuàng)建動(dòng)態(tài)查詢語句,這點(diǎn)原生 SQLHQL 都沒有 Criteria 好。

還是那句話,存在就是合理的。

如果,你對(duì)原生 SQL 有情懷,Criteria 查詢中也是可以用的。

criteria.add( Restrictions.sqlRestriction("stuId>2 and clasRoomId=1"));

注意,不要在 Sql 片段中使用 where 關(guān)鍵字。既然是原生 SQL,所以語句中是字段概念,而不是屬性概念。

前面講解 HQL 時(shí),提到了分頁查詢。Criteria 一樣可以實(shí)現(xiàn)分頁查詢,和 HQL 中分頁方法一樣:

Criteria criteria = session.createCriteria(Student.class);
criteria.setFirstResult(1);
criteria.setMaxResults(5);
List results = criteria.list();

2.2 高級(jí)查詢

排序查詢使用 order API 實(shí)現(xiàn):

criteria.addOrder(Order.desc("stuId"));
criteria.addOrder(Order.asc("stuName"));

一樣,可以多字段排序。

使用聚合函數(shù):聚合函數(shù)的功能封裝在 projections API 中:

criteria.setProjection(Projections.rowCount());
criteria.setProjection(Projections.avg("stuId"));
criteria.setProjection(Projections.max("stuId"));
criteria.setProjection(Projections.min("stuId"));
criteria.setProjection(Projections.sum("stuId"));

Criteria 也能實(shí)現(xiàn)關(guān)聯(lián)查詢:

Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.like("stuName", "Hibernate%"));
Criteria criteria01 = criteria.createCriteria("classRoom");
criteria01.add(Restrictions.like("classRoomName", "c19%"));
List<Student> students = criteria.list();

可以把一個(gè) Criteria 實(shí)例看成對(duì)一張表的查詢,如果需要關(guān)聯(lián)多張表,則可以通過一個(gè) Criteria 再創(chuàng)建一個(gè) Criteria 對(duì)象。

HibernateCriteria 查詢提供各種各樣的 API,適應(yīng)于任何查詢需求,相比較使用的已經(jīng)很普遍的 SQL 查詢,Criteria 查詢充滿了雞肋的味道。但對(duì)于動(dòng)態(tài)查詢需求,Criteria 查詢的優(yōu)勢(shì)又很明顯。

3. 原生 SQL 查詢

Hibernate 支持原生 SQL 查詢,對(duì)于熟悉并鐘情于 SQL 語句的開發(fā)者來講,是一個(gè)很大的福音。
實(shí)例:

String sql="select * from student";
SQLQuery sqlQuery= session.createSQLQuery(sql);

Hibernate 提供了一個(gè)與原生 SQL 有關(guān)的 SQLQuery 對(duì)象。SQLQueryQuery 的子類,可適應(yīng)不同的原生 SQL 語句查詢。

4. 小結(jié)

本節(jié)課和大家聊到了 Criteria 查詢,HQL 查詢,原生 SQL 查詢。原生 SQL 查詢無所不能,HQL 查詢是面向?qū)ο蟮?SQL ,具有混血身份。據(jù)說,混血的總是很美,也是建議大家選擇的一種查詢方案。

Criteria 查詢是 Hibernate 提供的一種純面向?qū)ο蟮慕鉀Q方案,但是,為了構(gòu)建一條 SQL 語句需要寫許多代碼,其應(yīng)用領(lǐng)域會(huì)相對(duì)較窄。

本節(jié)課給大家介紹 Criteria 的目的,一是擴(kuò)展學(xué)生的學(xué)習(xí)范圍,如果需要使用動(dòng)態(tài)查詢,Criteria 則有著無可比擬的優(yōu)越感。