員工表 department
CREATE TABLE `employee` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`age` int(11) NOT NULL,
`birthday` date default NULL,
`department_id` int(11) default NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`department_id`) REFERENCES `department` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.2.使用JPA註解配置實體類
部門類 Department
員工類 Employee
2.3使用Crteria查詢所有部門和所有員工
2.3.1查詢所有部門
產生的SQL語句:
查詢所有員工
產生的SQL語句:
當session.createCriteria(實體類.class) 就會產生一條select所有列from 表;SQL語句,查詢實體類對應數據表的所有記錄,然後我們就可以在這個Criteria對象上進行條件查詢、分頁查詢、多表關聯查詢、投影查詢、子查詢等一系列操作……
3.Criteria SQL定製詳解
3.1對查詢添加條件對象Criterion
org.hibernate.criterion.Criterion是Hibernate提供的一個面向對象查詢條件接口,一個單獨的查詢就是Criterion接口的一個實例,用於限制Criteria對象的查詢,在Hibernate中Criterion對象的創建通常是通過Restrictions 工廠類完成的。
Restrictions 提供條件查詢方法:
例如:
1、查詢姓“張”的所有員工信息
產生的SQL語句:
2、查詢年齡大於24的所有員工
產生的SQL語句:
3、查詢年齡小於28的姓“王”的員工
產生的SQL語句:
對於多個查詢條件,Restrictions提供了邏輯組合查詢方法。
and(Criterion lhs, Criterion rhs) 用於生成多個條件and關係SQL語句;
or(Criterion lhs, Criterion rhs) 用於生成多個條件or關係SQL語句;
not(Criterion expression) 用於查詢與條件相反的數據,生成not取反查詢語句。
3.2分頁操作 firstResult和maxResults
Criteria接口提供用於分頁查詢的方法,實現數據庫SQL物理級別的分頁操作。
setFirstResult(int firstResult)設置記錄的起始位置0代表第一條記錄。
setMaxResults(int maxResults)設置查詢記錄的長度。
例如:我要查詢1-10條件記錄firstResult爲0 ,maxResult爲10。
產生的SQL語句:
3.3排序操作 Order
Hibernate提供org.hibernate.criterion.Order用於排序操作, Criteria 接口提供addOrder(Order order)用於生成排序SQL。
例如:查詢所有員工信息,按照年齡升序排列。
產生的SQL語句:
Criteria接口提供createAlias 和 createCriteria 兩組方法用於完成多表關聯查詢。
createAlias(String associationPath, String alias) 採用內連接關聯。
createAlias(String associationPath, String alias, int joinType) 可以通過joinType指定連接類型。
createCriteria(String associationPath) 採用內連接關聯(返回新的Criteria對象)。
createCriteria(String associationPath, int joinType) 可以通過joinType指定關聯類型(返回新的Criteria對象 )。
例如:查詢部門爲“人力資源部”的所有員工。
方法一:使用createCriteria方法。
產生的SQL語句:
代碼中的criteria對象,是針對employee表,criteria.createCriteria(”department”) 就是建立employee表和department表的內連接。返回的是針對department表新的criteria2對象,這時再對criteria2 添加條件,就是查詢department部門表的屬性,而不是employee的屬性了。
方法二:使用createAlias 方法。
使用createAlias方法不會像createCriteria那樣返回一個新的Criteria對象,alias只是對關聯表進行別名設置,通過別名引用設置屬性。
產生的SQL語句:
3.5.投影、分組查詢 Projection
在實際開發中,進行查詢是:可能只需要返回表中的指定列信息(投影)或者進行統計查詢(count、avg、sum、min、max),Criteria接口提供setProjection(Projection projection)方法用於實現投影查詢操作。
org.hibernate.criterion.Projections工廠類用於返回Projection投影查詢對象。
例如: 1. 查詢員工表的name和age屬性。
產生的SQL語句:
Projections.property(屬性名)也可以寫爲Property.forName(屬性名 )。
2.查詢員工的總數量。
Projections提供了分組函數的查詢方法:
rowCount() 查詢記錄總數量;
count(String propertyName) 統計某列數量;
countDistinct(String propertyName) 統計某列數量(排除重複);
avg(String propertyName) 統計某列平均值;
sum(String propertyName) 對某列值求和;
max(String propertyName) 求某列最大值;
min(String propertyName) 求某列最小值。
產生的SQL語句:
3.查詢每個部門的員工數量(輸出部門的編號和數量 )。
Projections提供groupProperty(String propertyNam
-e)用於執行分組操作。
產生的SQL語句:
3.6. 設置結果集封裝策略 ResultTransformer
剛剛說了投影操作的使用,其實在Hibernate內部投影查詢是會影響到結果集的封裝策略的。先用HQL舉例說明:
session.createQuery(”from Employee”).list(); 返回 List
session.createQuery(”select count(e) from Employee e”).list(); 返回List
session.createQuery(”select name,age from Employee”).list(); 返回List
從這幾個例子我們不難發現,如果沒有指定select語句(沒有投影),那麼將返回表中的所有字段,返回結果會被封裝到Entity實體對象Employee中,一但提供select語句(投影)後,返回的結果類型,將不再封裝到Employee對象,而是根據投影的實際類型返回,這就是投影對結果封裝策略的影響。
我們再來看之前寫過的Criteria 查詢案例:
session.createCriteria(Employee.class).list();返回 List
session.createCriteria(Employee.class).setProjection(
Projections.projectionList()
.add(Property.forName(”name”))
.add(Property.forName(”age”))); 返回 List
投影之後,返回的結果將不再被封裝到Employee對象中,這是爲什麼呢?
我們一起來看看 Criteria的接口定義,不難發現在Criteria接口中提供了一個setResultTransformer(ResultTransformer resultTransformer),這個ResultTransformer就是結果集轉換策略接口,在Criteria的父接口中CriteriaSpecification定義了幾個ResultTransformer的常用實現。
ALIAS_TO_ENTITY_MAP 將結果集封裝到Map對象;
ROOT_ENTITY 將結果集封裝到根實體對象;
DISTINCT_ROOT_ENTITY 將結果集封裝到不重複的根實體對象;
PROJECTION 根據投影的結果類型自動封裝;
當進行投影查詢時,結果的封裝策略由ROOT_ENTITY 變爲了PROJECTION, 所以是根據查詢數據進行封裝,而不是封裝到根對象。
瞭解上面原理後,即使只查詢name和age屬性,也可以封裝成List集合。
使用AliasToBeanResultTransformer 修改結果封裝策略,AliasToBeanResultTransformer 會根據返回列自動匹配類中屬性名,完成封裝。
產生的SQL語句: