89-----hibernate的hql查詢,原生SQL查詢,命名查詢,投影查詢
HQL是Hibernate Query Language即Hibernate查詢語言
HQL(Hibernate Query Language)是面向物件的查詢語句
執行HQL語句可以採用兩種方式:
list()方法
iterator()方法
HQL語句中繫結引數的形式有兩種:
按引數位置繫結
按引數名字繫結
HQL支援投影查詢、引數查詢、分頁查詢等功能。
查詢所有部門:from Dept
HQL語法舉例:
from cn.jbit.hibernatdemo.entity.Dept
select dept from Dept as dept
from Dept where deptName = 'SALES'
from Dept dept where dept.location is not null
from Emp order by hireDate,salary desc
執行HQL語句的步驟:
編寫HQL語句;
建立Query物件;
執行查詢,得到查詢結果。
session = sessionFactory.openSession();
String hql = "from Emp";
Query query = session.createQuery(hql);
List<Emp> empList = query.list();
HQL查詢語句
在HQL查詢語句中繫結引數:String hql = "from User where name ='" + name + "'";在HQL查詢方法二:from Emp where job like ? and ename=:n
query.setParameter("n", name);query.setParameter(0, "%保潔%");
HQL投影查詢是查詢一個持久化類的一個或多個屬性值
將每條查詢結果封裝成Object陣列
將每條查詢結果通過建構函式封裝成物件
//投影查詢方法1:直接使用select 屬性 from 類名的方式查詢
public void list1(){ Session session = HibernateSessionFactory.getSessionFactory().getCurrentSession(); //開啟事務 Transaction tx = session.beginTransaction(); Query query = session.createQuery("select name,title from Guestbook"); List<Object[]> list = query.list(); for(Object[] o:list){ System.out.println("姓名:"+o[0]); } tx.commit(); }
/*
* 投影查詢方法2 --- 使用select new 類名(屬性名...) from 類名的方式,返回實體類
* 注意:如何使用實體類的方式,那麼必須在實體類中有這樣的構造方法
*/
/*
* 投影查詢方法3 --- 使用select new Map(屬性名...) from 類名的方式,返回Map集合,通過下標獲取屬性值
* 注意:如何使用實體類的方式,那麼必須在實體類中有這樣的構造方法
*/
public void list3(){
Session session = HibernateSessionFactory.getSessionFactory().getCurrentSession();
//開啟事務
Transaction tx = session.beginTransaction();
//在遍歷Map是就可以根據編號獲取屬性值
//Query query = session.createQuery("select new Map(id,name,title) from Guestbook");
//使用屬性的別名,在遍歷Map是就可以根據名稱獲取屬性值
Query query = session.createQuery("select new Map(gb.id as id,gb.name as name,gb.title as title) from Guestbook gb");
List<Map> list = query.list();
for(Map m:list){
//注意:這裡的編號不是Integer型別,而是String型別
System.out.println("編號:"+m.get("id")+",姓名:"+m.get("name")+",標題:"+m.get("title"));
}
tx.commit();
}
分頁查詢:
uniqueResult()方法:獲取唯一物件setFirstResult()方法:設定從第幾條開始
setMaxResults()方法:設定讀取最大記錄數
String countHQL = "select count(*) from Dept";
int count = ((Long)session.createQuery(countHQL)
.uniqueResult()).intValue();
int totalpages = (count % pageSize == 0)
? (count / pageSize) : (count / pageSize + 1);
int pageIndex = 1;
query.setFirstResult((pageIndex - 1) * pageSize);
query.setMaxResults(pageSize);
List<Dept> deptList = query.list();
一、 子查詢語句應用在HQL查詢語句的where子句中
all返回的所有記錄
any返回的任意一條記錄
some和“any”意思相同
in與“=any”意思相同
exists至少返回一條記錄
查詢工資高於平均工資的員工。
"fromEmp ewheree.salary>(selectavg(salary)fromEmp)"
查詢所有員工工資都小於5000的部門。
"fromDept dwhere 5000>all(selecte.salary fromd.emps e) andd.emps.size>0"
查詢至少有一位員工工資低於5000的部門。
"fromDept dwhere 5000>any(selecte.salary fromd.emps e)"
查詢至少有一位員工的部門
"fromDept dwhere exists (fromd.emps)"
查詢員工工資正好是5000元的部門
"fromDept dwhere 5000 in (selecte.salary fromd.emps e)"
"fromDept dwhere 5000=some(selecte.salary fromd.emps e)"
"fromDept dwhere 5000=any(selecte.salary fromd.emps e)"
查詢指定員工所在部門
"fromDeptd where ? in (fromd.emps)"
"fromDeptd where ? in elements (d.emps)"
查詢員工個數大於5的部門
"fromDeptd where d.emps.size>5"
"fromDeptd where size(d.emps)>5"
二、 聚合函式
count()統計記錄條數sum()求和
max()求最大值
min()求最小值
avg()求平均值
按職位統計員工個數。select job,count(*)from Employee group by job
統計各個部門的平均工資 select e.dept.dname,avg(sal)from Employee egroup by e.dept.dname
統計各個職位的最低工資和最高工資 selecte.job,max(sal),min(sal)from Employee e group by e.job
統計各個部門平均工資高於4000元的部門名稱,列印部門名稱、部門平均工資
selecte.dept.dname,avg(sal)from Employee e group by e.dept.dname havingavg(sal)>2000
統計各個部門平均工資高於4000元的部門名稱,列印部門名稱、部門平均工資,使用JavaBean封裝查詢結果
三、 相關例子
查詢有50條以上房屋資訊的街道。
查詢所有房屋資訊的租金高於2000元的的街道。
查詢至少有一條房屋資訊的租金低於1000元的街道。
統計各個街道的房屋資訊條數。
fromStreet s where 50<(select count(h) froms.houses h)
fromStreet s where 2000<all(selecth.price froms.houses h) ands.houses.size>0
fromStreet s where 1000> any (selecth.price froms.houses h)
selects.name,s.houses.size from Street s
四、 HQL的連線查詢
使用隱式內連線查詢某使用者釋出的房屋資訊 (提示:from House h where h.user.uname = 'rose')
連線型別HQL語法
內連線 inner join 或 join
迫切內連線inner join fetch或 join fetch
左外連線left outer join或 left join
迫切左外連線left outer join fetch或 left join fetch
右外連線right outer join 或right join
HQL使用group by關鍵字對資料分組,用having關鍵字對分組資料設定約束條件
Hibernate可以在對映檔案中定義字串形式的查詢語句
Hibernate使用Session的createSQLQuery()方法建立SQLQuery物件,用來執行原生SQL語句
在持久化類中,二進位制大物件可以宣告為byte[]或java.sql.Blob型別;字串大物件可以宣告為java.lang.String或java.sql.Clob型別
五、 原生SQL查詢
Query query = session
.createSQLQuery(
"select * from EMP where ENAME like :ename and JOB = :job")
.addEntity(Emp.class).setString("ename", "%e%")
.setString("job", "ENGINEER");
List<Emp> list = query.list();
String sql = "select {e.*},{d.*} from EMP e join DEPT d on d.DEPTNO=e.DEPTNO"+ " where e.JOB = :job";
Query query = session.createSQLQuery(sql).addEntity("e", Emp.class).addJoin("d", "e.dept").setString("job", "ENGINEER");
<sql-query name="selectEmpByJob">
<return alias="e" class="cn.jbit.hibernatedemo.entity.Emp"/>
select {e.*} from EMP e where e.job = :job
</sql-query>
<sql-query name="selectEmpByJobJoinDept">
<return alias="e" class="cn.jbit.hibernatedemo.entity.Emp"/>
<return-join alias="d" property="e.dept"></return-join>
select {e.*},{d.*} from EMP e join DEPT d on d.DEPTNO=e.DEPTNO where e.JOB = :job
</sql-query>
六、 命名查詢
<hibernate-mapping>
<class name="cn.jbit.hibernatedemo.entity.Emp" table="emp">
......
</class>
<sql-query name="selectEmpByJob">
<return alias="e" class="cn.jbit.hibernatedemo.entity.Emp"/>
select {e.*} from EMP e where e.job = :job
</sql-query>
</hibernate-mapping>
<hibernate-mapping>
<class name="cn.jbit.hibernatedemo.entity.Emp" table="emp">
......
</class>
<query name="findEmpByJob">
<![CDATA[
from Emp e where e.job = :job
]]>
</query>
</hibernate-mapping>
原生sql查詢
SQLQuerysession.createSQLQuery("sql");
命名查詢
對映檔案
根標籤下<queryname="N"><![CDATA[Hql]]>
session.getNamedQuery("N");
原生sql命名查詢
對映檔案
根標籤下<sql-queryname="N"><return class=""/>sql</>
session.getNamedQuery("N");
八、