1. 程式人生 > >89-----hibernate的hql查詢,原生SQL查詢,命名查詢,投影查詢

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語句的步驟:

獲取Session物件
編寫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物件
將每條查詢結果封裝成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 類名的方式,返回實體類
 * 注意:如何使用實體類的方式,那麼必須在實體類中有這樣的構造方法
 */

public void list2(){ Session session = HibernateSessionFactory.getSessionFactory().getCurrentSession(); //開啟事務 Transaction tx = session.beginTransaction(); Query query = session.createQuery("select new Guestbook(id,name,title) from Guestbook"); List<Guestbook> list = query.list(); for(Guestbook gb:list){ System.out.println("編號:"+gb.getId()+",姓名:"+gb.getName()+",標題:"+gb.getTitle()); } tx.commit(); }

/*
 * 投影查詢方法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");

八、