Hibernate 複合查詢
複合查詢主要是處理,具有關聯關係的兩個實體怎樣進行關聯查詢,比如
User
實體對象與
Addres
實體對象具有一對多的關聯關係,我們可以如下構造符合查詢:
Criteria criteria=session.createCriteria(User.class);
Criteria addcriteria=criteria.createCriteria(“addresses”);(1)
addcriteria.add(Express.like(“address”,”%tianjin%”));
List list=criteria.list();
for(int i=0;i
User user=(User)list.get(i);
System.out.println(user.getName()+”/n”);
Set addresses=user.getAddresses();
Iterator it=addresses.iterator();
while(it.hasNext(){
Address address=(Address)it.next();
System.out.println(address.getAddress()+”/n”);
}
}
當執行到了(
1
)處時,表明要針對
User
對象的
addresses
屬性添加新的查詢條件,因此當執行
criteria.list()
時,
Hibernate
會生成類似如下的
SQL
語句:
Select * from user inner join address on user.id=address.id where address.address like ‘%shanghai%’;
正如我們所見,我們可以通過向
Criteria
中添加保存關聯對象的集合屬性(
addresses
屬性保存與
User
對象相關聯的
Address
對象),來構造複合查詢,在數據庫一端是通過內連接查詢來實現。
相關:
1. Hibernate
2.
QBC
查詢:
QBC
查詢就是通過使用
Hibernate
提供的
Query By Criteria API
來查詢對象,這種
API
封裝了
SQL
語句的動態拼裝,對查詢提供了更加面向對象的功能接口。我們看下面的示例程序:
Criteria criteria=session.createCriteria(User.class);
criteria.add(Expression.eq(“name”,”zx”));
criteria.add(Expression.eq(“age”,new Integer(27));
List list=criteria.list();
當執行
criteria.list()
時會生成類似這樣的
SQL
語句:
Select * from user where name=’zx’ and age=27;
所以在這裏我們可以看出,
Criteria
實際上是一個查詢容器,它對查詢條件表達式的添加進行了封裝,具體的查詢條件是通過
add()
方法添加的,而且具體的查詢條件的表達式運算是通過
Expression
指定的。
Hibernate
在運行期會根據
Criteria
指定的表達式條件來添加查詢條件,並且生成查詢語句。這種方式非常符合
Java
以及所有面向對象編程語言的編程方式,所以大多數的持久層框架都提供了對這種方式查詢的支持。下面我們講解這種查詢方式的各個技術細節。
1、
Criteria
查詢表達式:
正如我們所見,
Expression
對查詢語句的表達式進行了封裝和限制,下表列出了
Expression
所有的方法,以及每個方法所對應的查詢表達式及其限制。
方法
描述
Expression.eq
對應
SQL
的“
field=value
”表達式
如:
Expression.eq(“name”,”zx”);
Expression.allEq
方法的參數爲一個
Map
類型對象,包含多個名
/
值對對應關係,相當於多個
Expression.eq
的疊加
Expression.gt
對應
SQL
的“
field>value
”表達式
Expression.ge
對應
SQL
的“
field>=value
”表達式
Expression.lt
對應
SQL
的“
field
”表達式
Expression.le
對應
SQL
的“
field<=value
”表達式
Expression.between
對應
SQL
語句的
between
表達式,如:查詢年齡在
21
與
27
歲之間的用戶,可以寫成
Expression.between(“age”,new Integer(21),new Integer(27));
Expression.like
對應
SQL
語句的
”field like value”
表達式
Expression.in
對應
SQL
語句的“
field in(……)
”表達式
Expression.eqProperty
用於比較兩個屬性值,對應
”field=field”SQL
表達式
Expression.gtProperty
用於比較兩個屬性值,對應
”field>field”SQL
表達式
Expression.geProperty
用於比較兩個屬性值,對應
”field>=field”SQL
表達式
Expression.ltProperty
用於比較兩個屬性值,對應
”field
表達式
Expression.leProperty
用於比較兩個屬性值,對應
”field<=field”SQL
表達式
Expression.and
對應
SQL
語句的
And
關係組合,如:
Expression.and(Expression.eq(“name”,”zx”),Expression.eq(“sex”,”1”));
Expression.or
對應
SQL
語句的
Or
關係組合,如:
Expression.or(Expression.eq(“name”,”zx”),Expression.eq(“name”,”zhaoxin”));
Expression.sql
作爲補充這個方法提供了原生
SQL
語句查詢的支持,在執行時直接通過原生
SQL
語句進行限定,如:
Expression.sql(“lower({alias}.name) like (?)”,“zhao%”,Hibernate.STRING) ;
在運行時
{ alias }
將會由當前查詢所關聯的實體類名替換,
()
中的
?
將會由
”zhao%”
替換,並且類型由
Hibernate.STRING
指定。
注意:
Expression
各方法中的屬性參數(各方法中的第一個參數)所指定的屬性名稱(如:
name,sex
),並不是數據庫表中的實際字段名稱,而是實體對象中映射實際數據表字段的類屬性名稱。
2、
示例查詢:
示例查詢是通過
Example
類來完成的,
Example
類實現了
Criterion
接口,可以用作
Criteria
查詢條件,
Example
類的作用是:根據已有對象,查詢屬性值與之相同的其他對象。如下代碼所示:
Criteria criteria=session.createCriteria(User.class);
User exampleuser=new User(“zx”);
criteria.add(Example.create(exampleuser));
List list=criteria.list();
for(int i=0;i
User user=(User)list.get(i);
System.out.println(user.getName()+”/n”);
}
上述代碼中
User exampleuser=new User(“zx”);criteria.add(Example.create(exampleuser));
兩句相當於
criteria.add(Expression.eq(“name”,”zx”));
因此會生成類似如下的
SQL
語句:
select * from user where name=’zx’;
在上面的代碼中
exampleuser
稱爲示例對象。
在
Hibernate
中隊示例查詢,默認情況下會排除掉示例對象中屬性值爲空的屬性,還可以調用
Example.excludeNone
(排除空串值)
/excludeZeros
(排除零值),或者調用
Example.excludeProperty
方法來指定排除特定屬性。
示例查詢主要應用於組合查詢中,比如根據用戶輸入的查詢條件動態生成最終的查詢語句,通過使用示例查詢,可以避免由於查詢條件過多而寫的大量
if
判斷語句。
3、
複合查詢:
複合查詢主要是處理,具有關聯關係的兩個實體怎樣進行關聯查詢,比如
User
實體對象與
Addres
實體對象具有一對多的關聯關係,我們可以如下構造符合查詢:
Criteria criteria=session.createCriteria(User.class);
Criteria addcriteria=criteria.createCriteria(“addresses”);(1)
addcriteria.add(Express.like(“address”,”%tianjin%”));
List list=criteria.list();
for(int i=0;i
User user=(User)list.get(i);
System.out.println(user.getName()+”/n”);
Set addresses=user.getAddresses();
Iterator it=addresses.iterator();
while(it.hasNext(){
Address address=(Address)it.next();
System.out.println(address.getAddress()+”/n”);
}
}
當執行到了(
1
)處時,表明要針對
User
對象的
addresses
屬性添加新的查詢條件,因此當執行
criteria.list()
時,
Hibernate
會生成類似如下的
SQL
語句:
Select * from user inner join address on user.id=address.id where address.address like ‘%shanghai%’;
正如我們所見,我們可以通過向
Criteria
中添加保存關聯對象的集合屬性(
addresses
屬性保存與
User
對象相關聯的
Address
對象),來構造複合查詢,在數據庫一端是通過內連接查詢來實現。
4、
Criteria
的高級特性:
A、
限定返回記錄條數:
我們可以通過利用
Criteria.setFirstResult/setMaxResult
方法來限定返回某一次查詢的記錄數,如下代碼:
Criteria criteria=session.createCriteria(User.class);
criteria.setFirstResult(100);
criteria.setMaxResult(200);
通過以上代碼可以設定該次查詢返回
user
表中的從第
100
條記錄開始直到第
200
條記錄結束的
100
條記錄。
B、
對查詢結果進行排序:
可通過使用
net.sf.hibernate.expression.Order
類可以對查詢結果集進行排序,如下面代碼:
Criteria criteria=session.createCriteria(User.class);
criteria.add(Expression.eq(“groupid”,”2”);
criteria.addOrder(Order.asc(“name”));
criteria.addOrder(Order.desc(“groupid”));
List list=criteria.list();
通過使用
Order
類的
asc()/desc()
方法,可以指定針對某個字段的排序邏輯,如果執行上述代碼,會生成類似如下的
SQL
語句:
Select * from user where groupid=’2’ order by name asc,groupid desc
C、
分組與統計:
在
Hibernate3
中,對
Criteria
又增添了新功能,可以支持分組與統計功能,在
Hibernate3
中增加了
Projections
以及
ProjectionList
類,這兩個類對分組與統計功能進行了封裝,如下代碼:
Criteria criteria=session.createCriteria(User.class);
criteria.setProjection(Projections.groupProperty(“age”));(1)
List list=criteria.list();
Iterator it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
通過(
1
)處的代碼,我們通過
Projections
類指定了用於分組的目標屬性,當進行檢索時
Hibernate
會生成類似如下的
SQL
語句:
Select age from user group by age;
還可以通過使用
Projections
的
avg()/rowCount()/count()/max()/min()/countDistinct()
等方法來實現統計功能,如下面的代碼示例:
Criteria criteria=session.createCriteria(User.class);
criteria.setProjection(Projections.avg(“age”));(1)
List list=criteria.list();
Iterator it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
通過(
1
)處的代碼,我們實現了對用戶平均年齡的統計,當進行檢索時,
Hibernate
會生成類似如下的
SQL
語句:
Select avg(age) from user;
另外,在
SQL
語句中的多條件分組與統計功能,可以利用
ProjectionList
類來實現,如下面代碼所示:
Criteria criteria=session.createCriteria(User.class);
ProjectionList prolist=Projections.projectionList();
prolist.add(Projections.groupProperty(“age”));
prolist.add(Projections.rowCount());
criteria.setProjection(prolist);
List list=criteria.list();
通過以上代碼,實現了對不同年齡人員數量的分組統計,當進行檢索時,
Hibernate
會生成類似如下的
SQL
語句:
Select age,count(*) from user group by age;
5、
DetachedCriteria:
在
Hibernate2
中,
Criteria
實例是與創建它的
Session
實例具有相同的生命週期的,也就是說,
Session
實例是它所創建的
Criteria
實例的宿主,當
Session
關閉時,寄生於
Session
實例的
Criteria
都將失效。這就對
Criteria
的重用造成了困難,爲了實現
Criteria
實例的重用,在
Hibernate3
中提供了一個
DetachedCriteria
類,
DetachedCriteria
實例的生命週期與
Session
實例的生命週期無關,我們可以利用
DetachedCriteria
對一些常用的
Criteria
查詢條件進行抽離,當需要進行檢索時再與
Session
實例關聯,從而獲得運行期的
Criteria
實例。如下面的代碼所示:
DetachedCriteria dc= DetachedCriteria.forClass(User.class);
dc.add(Expression.eq(“name”,”zhaoxin”));
dc.add(Expression.eq(“sex”,”1”));
Criteria criteria=dc.getExecutableCriteria(session);
Iterator it=criteria.list().iterator();
while(it.hasNext()){
User user=(User)it.next();
System.out.println(user.getName());
}
正如我們所見,
DetachedCriteria
的生存週期與
session
實例無關,當需要進行檢索時,通過
getExecutableCriteria(session)
方法,與當前的
Session
實例關聯並獲得運行期的
Criteria
實例,完成檢索。
DetachedCriteria
也可以用於完成子查詢功能,如下代碼所示:
DetachedCriteria dc= DetachedCriteria.forClass(User.class);
dc.setProjection(Projections.avg(“age”));
Criteria criteria=session.createCriteria(User.class);
criteria.add(Subqueries.propertyGt(“age”,dc));
List list=criteria.list();
通過
Subqueries
類,實現了添加子查詢的功能,我們將
DetachedCriteria
所設定的查詢條件,當作子查詢添加到了運行時
Criteria
實例的查詢條件中,當執行檢索時
Hibernate
會生成類似如下的
SQL
語句:
Select * from user where age>(select avg(age) from user group by age);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.