Hibernate 笔记 HQL查询
http://www.cnblogs.com/zilong882008/archive/2011/11/05/2237123.html
Hibernate 筆記 HQL查詢(一)單屬性,多屬性查詢
HQL是Hiberante官方推薦的Hibernate檢索方式,它使用類似SQL的查詢語言,以面向對象的方式從數據庫中查詢。可以使用HQL查詢具有繼承、多態和關聯關系的數據。在檢索數據時應優先考慮使用HQL方式。
本筆記將會沿用前面所使用的dept部門表,emp員工表。
dept部門表
emp員工表
1 查詢實體
???? hibernate的session.createQuery()方法是使用HQL語句查詢對象的。
???? hql:是查詢對象的,例如:"from User",其中from不區分大小寫,而User是區分大小寫,因為它是對象。是User類
?????返回Query對象。
?????執行這條語句后,Hibernate會根據配置文件中所配置的數據庫適配器自動生成相應數據庫的SQL語句。
sql: select * from dept;???? from 后面是表名
hql: form Dept;??? from 后面是類。
可以對類起別名,有兩種方法。
hql: from Dept d
hql:from Dept as d
以上兩種起別名方法皆可。
public void Test1() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String hql="from Dept"; //定義String類型hql,寫入hql語句。 Query query=session.createQuery(hql); List<Dept> list = query.list(); for(Dept dept:list){ System.out.print("部門編號: "+dept.getDid() +" "); System.out.println("部門名稱: "+dept.getDname()); } tr.commit(); }catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}執行結果
Hibernate: select dept0_.did as did1_, dept0_.dname as dname1_, dept0_.daddress as daddress1_ from dept dept0_
部門編號:? 1?? 部門名稱:?? 業務部
部門編號:? 2?? 部門名稱:?? 技術部
部門編號:? 3?? 部門名稱:?? 管理部
部門編號:? 4?? 部門名稱:?? 財務部
部門編號:? 5?? 部門名稱:?? 人力資源部
?
2? 查詢表中單個屬性
sql: select ename from dept
hql: select ename from Dept
對屬性也可以設置別名
hql:select ename as from Dept
as 必須加。
public void Test2() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); Query query=session.createQuery("select dname from Dept"); List<String> list = query.list(); for(String name:list){ System.out.println("部門名稱: "+name); } tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}?
?執行結果:
Hibernate: select dept0_.dname as col_0_0_ from dept dept0_
部門名稱: 業務部
部門名稱: 技術部
部門名稱: 管理部
部門名稱: 財務部
部門名稱: 人力資源部
3? 對多個屬性進行查詢
sql: select ename,eage from emp
hql:select ename,eage from Emp
hql: select e.ename,e.eage from Emp e
以上兩種hql寫法均可。
public void Test3() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); Query query=session.createQuery("select ename,eage from Emp"); List<Object[]> list = query.list(); //對多個屬性查詢的時候,使用Obejct數組。 for(Object[] message:list){ System.out.println(Arrays.toString(message)); //采用輔助類Arrays的toString()方法打印數組。 } tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}?
測試結果
Hibernate: select emp0_.ename as col_0_0_, emp0_.eage as col_1_0_ from emp emp0_
[劉德華, 40]
[李世民, 34]
[曹操, 59]
[和珅, 44]
[賀龍, 45]
[郭富城, 34]
4 通過實體類方式查詢多屬性
除了上述方法外,還可以采用實體類的方式查詢,要在Emp類中加入帶有查詢參數的構造器,代碼如下。
public class Emp {private int eid;private int eage;private float esal;private String ename; 省略get,set方法。public Emp() {super(); } public Emp(int eage, String ename) { //需要查詢的屬性是什么,構造器的參數就是什么。super();this.eage = eage;this.ename = ename; }?
?
測試類
public void Test4() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); Query query=session.createQuery("select new Emp(eage,ename) from Emp e"); select 后直接調用構造器,參數就是查詢的屬性,參數不可錯亂。 List<Emp> list = query.list(); 此處不實用object數組,類類型即可 for(Emp message:list){ System.out.print("姓名:"+message.getEname()+" "); System.out.println("年齡:"+message.getEage()); } tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}測試結果
Hibernate: select emp0_.eage as col_0_0_, emp0_.ename as col_1_0_ from emp emp0_
姓名:劉德華? 年齡:40
姓名:李世民? 年齡:34
姓名:曹操? 年齡:59
姓名:和珅? 年齡:44
姓名:賀龍? 年齡:45
姓名:郭富城? 年齡:34
Hibernate 筆記 HQL查詢(二)條件查詢,聚集函數,子查詢,導航查詢
本筆記繼續使用dept部門表,emp員工表,一對多多對一雙向映射。
1 條件查詢
1.1??? 查詢 員工表emp中 年齡eage小于30,月薪esal大于20000的員工姓名ename
sql:select ename from emp where eage<? and esal >?;
hql: select ename from Emp where eage<? and esal >?
1.2 問號的設置與別名
?問號(?)的設置使用.setParameter(位置, 屬性值) 在sql語句中問號的位置是從1開始,在hql中從零開始。
?在hql中,問號(?)也可以起別用,:后面緊跟別名,setParameter("age", 30)方法也隨之改變,將原先的數字改成"別名",如下所示
???????? ??? String hql="select ename from Emp where eage<:age and esal >:sal";
?????????? ? Query query= session.createQuery(hql).setParameter("age", 30).setParameter("sal", 20000f).list();???
1.3?? 一組問號的設置
?????? 對于一組問號也可以設置別名:如 查詢在1,2部門的員工姓名
???????????? hql="select ename from Emp where did in (?,?)";
?????????????hql="select ename from Emp where did in (:d)";
?????????????Query query= session.createQuery(hql).setParameter("d", new Object[]{1,2}).list();
?
public void Test9() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String hql="select ename from Emp where eage<? and esal >?"; Query query= session.createQuery(hql).setParameter(0, 30).setParameter(1, 20000f); //設置問號,從0開始。 List<String> list = query.list(); for(String message:list){ System.out.println(message); } tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}結果:
Hibernate: select emp0_.ename as col_0_0_ from emp emp0_ where emp0_.eage<? and emp0_.esal>?
劉亦菲
白百何
文章
林月如
?
2 條件查詢的常用關鍵字
????2.1? distinct? 過濾重復的值
??????????? 查詢員工表中的所有員工姓名,并去掉重復值
??????????? hql="select distinct? ename from Emp ";??
????2.2? delete?? 刪除
???????????? 刪除年齡大于25的員工
? hql="delete Emp where eage>25"; 刪除年齡大于25歲的用戶
??????????? Query query=session.createQuery(hql);
?? ? query.executeUpdate();?????????? //執行? executeUpdate 方法返回int類型。
? tx.commit();???? ?????? //成功,則提交,對數據庫操作
????2.3? update 更新
?????????? 更新員工編號11的年齡為22
String hql="update Emp s set s.eage='22' where s.eid=11";?? //更新語句
?? ? Query query=session.createQuery(hql);
????????? ?query.executeUpdate();?????????? //執行
????????? ?tx.commit();?????????? //成功,則提交
??? 2.4? between...and...和not between... and...確定查詢范圍
???????? ?查找員工表中年齡在20到30之間的員工姓名
????????? hql="select ename from Emp where eage between 20 and 30"
2.5??in和not in確定查詢集合
?????????? 查詢員工屬于低1,2部門的員工姓名
????????? hql="select ename from Emp where did in(1,2)"
??? 2.6? like進行模糊查詢
????????? 用like進行模糊查詢時有兩個可用的通配符:“%”和“_”。“%”代表長度大于等于0的字符,“_”代表長度為1的單個字符。
????????? 查詢員工表中姓名中帶有劉的員工
????????? hql="select ename from Emp where ename? like '%劉%'"
? ?? 2.7? 邏輯與 and 邏輯或 or
????????? 查詢員工中薪水大于2000 同時年齡小于30的員工姓名
??????????hql="select ename from Emp where esal>2000 and eage<30";
????????? 查詢員工中,年齡大于40或者年齡小于30的員工
????????? hql="select ename? from Emp where eage>40 or eage<30";
???? 2.8??order by對結果進行排序
???????? 對薪水進行排序,從小到大
?????????hql="select esal from Emp where order by esal asc";
???????? 對年齡進行排序,倒敘,
???????? hql="select ename from Emp where order by eage desc";
?????2.9? group by對記錄進行分組
??????? 根據部門分組,求出各組的平均薪水
????????hql=" select avg(esal) from Emp group by did";
???? 2.10 having 對分組進行篩選
????????? 根據部門分組,查出員工所在組平均薪水大于10000的員工姓名
??????????hql="?select?ename from Emp group by did having? avg(esal)>10000";
?
3 聚集函數
查詢emp員工表中有多少個員工。
sql:select count(ename) from emp;
hql: select count(ename) from Emp;
聚集函數及含義:
hql: select avg(esal) from Emp;?? 薪水平均值
hql: select max(esal) from Emp;? 薪水最大值
hql: select sum(esal) from Emp;? 薪水最小值
public void Test91() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String hql="select count(ename) from Emp";Object count=session.createQuery(hql).uniqueResult(); //uniqueResult()方法返回Object類型? System.out.println(count); tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}?
結果:
Hibernate: select count(emp0_.ename) as col_0_0_ from emp emp0_
15
?
?4 子查詢
Hibernate 支持子查詢,所謂子查詢就是,要查詢的字段及信息在A表,條件在B表。語法與sql語句相似。
public void Test9() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String hql="select ename from Emp where did in (select did from Dept where daddress = 302)"; Query query= session.createQuery(hql); List<String> list = query.list(); for(String message:list){ System.out.println(message); } tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}結果:
Hibernate: select emp0_.ename as col_0_0_ from emp emp0_ where did in (select dept1_.did from dept dept1_ where dept1_.daddress=302)
李世民
曹操
和珅
劉詩詩
?
5 導航查詢
?e.dept.daddress=301
員工所在部門的地址是301
public void Test9() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String hql="select ename from Emp e where e.dept.daddress=301 "; Query query= session.createQuery(hql); List<String> list = query.list(); for(String message:list){ System.out.println(message); } tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}結果:
Hibernate: select emp0_.ename as col_0_0_ from emp emp0_, dept dept1_ where emp0_.did=dept1_.did and dept1_.daddress=301
劉德華
賀龍
白百何
文章
林月如
Hibernate 筆記 HQL查詢(三) 分頁,表連接,批量更新,引用SQL
1 分頁
??? ??setFirstResult(0),(從0開始)
???? setMaxResults(5),每頁顯示5條數據
public void Test1() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String hql="select eage from Emp order by eage"; Query query= session.createQuery(hql).setFirstResult(0).setMaxResults(5); //從0開始,現實5條數據。 List<Integer> list = query.list(); for(Integer message:list){ System.out.println(message); } tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}Hibernate: select emp0_.eage as col_0_0_ from emp emp0_ order by emp0_.eage limit ?
21
21
24
24
24
2?表連接
Hibernate 支持內鏈接和外鏈接(左連接,右連接)
hql: from Emp e? inner join fetch e.dept;?? 內鏈接
hql: from Emp e? left?join fetch e.dept;?????左連接
hql:from Emp e right join fetch e.dept???? 右連接
public void Test2() throws Exception{ //實體 Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction();Query query=session.createQuery("from Emp e inner join fetch e.dept where eage<30");List<Emp> list = query.list();for(Emp user:list){System.out.println(user.getEname());System.out.println(user.getDept().getDaddress()); tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}結果
Hibernate: select emp0_.eid as eid2_0_, dept1_.did as did1_1_, emp0_.ename as ename2_0_, emp0_.eage as eage2_0_, emp0_.esal as esal2_0_, emp0_.did as did2_0_, dept1_.dname as dname1_1_, dept1_.daddress as daddress1_1_ from emp emp0_ inner join dept dept1_ on emp0_.did=dept1_.did where eage<30
白百何
301
文章
301
林月如
301
劉詩詩
302
3 批量更新
將年齡在25歲一下的員工改成25歲
hql="update Emp e set e.eage=25 where e.eage<25";
刪除25歲一下的員工
hql="delete Emp?e where e.eage<25";
使用executeUpdate()方法必須啟用事務。
public void Test3() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String hql="update Emp e set e.eage=25 where e.eage<25"; Query query=session.createQuery(hql); query.executeUpdate(); tr.commit(); }catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}?
4 Hibernate 中使用SQL
HQL不是萬能的,無法執行插入語句和非常復雜的查詢,Hibernate 也支持SQL查詢。通過連接直接調用cerateSQLQuery(sql)即可
sql語句中存在問號,同樣使用setParameter(位置,屬性值)方法設置。問號的位置從0開始,最后調用executeUpdate執行。事務提交后數據庫開始工作。
public void Test4() throws Exception{ Configuration config=new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session=null;Transaction tr=null;try{session= sessionFactory.openSession();tr=session.beginTransaction(); String sql="insert into emp (ename,eage) values (?,?)"; session.createSQLQuery(sql).setParameter(0, "曹雪芹").setParameter(1, 22).executeUpdate(); tr.commit();}catch(Exception e){tr.rollback();}finally{if(session!=null){session.close();}if(sessionFactory!=null){sessionFactory.close();}}}?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Hibernate 笔记 HQL查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javax.xml.datatype.X
- 下一篇: JUnit学习摘要+入门实例 (juni