熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Hibernate數據查詢

2022-06-13   來源: Java核心技術 

  Hibernate Query Language(HQL)

  Criteria Query

  Native SQL

  下面對其分別進行解釋

  Hibernate Query Language:

  HQL提供了是十分強大的功能它是針對持久化對象用取得對象而不進行updatedelete和insert等操作而且HQL是面向對象的具備繼承多態和關聯等特性

  from子句

  from子句是最簡單的HQL例如from Student也可以寫成 select s from Student s它簡單的返回Student類的所有實例

  值得注意的是除了JAVA類和屬性的名稱外HQL語句對大小寫不敏感

  select子句

  有時並不需要取得對象的所有屬性這時可以使用select子句進行屬性查詢如select sname from Student s

  例 public void HQLselectDEMO()

  {

  TRegister user = new TRegister();

  Session session = HibernateUtilcurrentSession();

  Query query = sessioncreateQuery(select uuserName from TRegister u);

  List list = querylist();

  for(int i = ; i < listsize(); i++)

  {

  String name = (String)listget(i);

  Systemoutprintln(name);

  }

  }如果要查詢兩個以上的屬性桧以數組的方式返回如下 public void HQLselectDEMO()

  {

  TRegister user = new TRegister();

  Session session = HibernateUtilcurrentSession();

  Query query = sessioncreateQuery(select uuserName usex from TRegister u);

  List list = querylist();

  for(int i = ; i < listsize(); i++)

  {

  Object obj[] = (Object[])listget(i);

  Systemoutprintln(obj[]+    的性別是+obj[]);

  }

  }

  在使用屬性查詢時由於使用對象數組操作和理解不太方便如果將 一個object[]中所有成員封裝成一個對象就方便多了下面的程序做了示例 public void HQLselectDEMO()

  {

  Session session = HibernateUtilcurrentSession();

  Query query = sessioncreateQuery(select new TRegister(uuserNameusex) from TRegister u);

  List list = querylist();

  for(int i = ; i < listsize(); i++)

  {

  //Object obj[] = (Object[])listget(i);

  TRegister user = (TRegister)listget(i);

  Systemoutprintln(usergetUserName()+    的性別是+usergetSex());

  }

  /** *//**要正確運行以上程序需要在TRegister類中加入一個相應的構造函數

  public TRegister(String userNameString sex) {

  thisuserName = userName;

  thissex = sex;

  }

  */

  }

  統計函數查詢

  可以在HQL中使用函數經常使用的函數如下

  count()統計記錄條數

  min()求最小值

  max()求最大值

  sum()求和

  avg()求平均值

  例如要取得Student實例的數量可以編寫如下HQL語句

  select count(*) from Student

  取得Student平均年齡的HQL語句

  select avg(sage) from Student as s

  可以使用distinct去除重復的數據

  select distinct sage from Student as s

  where子句

  HQL也支持子查詢它通過where子句實現這一機制where子句可以讓用戶縮小要返回的實例的列表范圍例如下面語句會返回所有名字為Bill的Student實例

  Query query = sessioncreateQuery(from Student as s where sname=Bill);

  where子句允許出現的表達式包括了SQL中可以使用的大多數情況

  數學操作+*/

  真假比較操作= >= <= <> != like

  邏輯操作and or not

  字符串連接||

  SQL標題函數 如upper()和lower()

  如果查詢返回多條記錄可以用以下關鍵字來量化

  all表示所有的記錄

  any表示所有記錄中的任意一條

  some與any相同

  in與any等價

  exists表示子查詢至少要返回一條記錄

  例如下面語句返回所有學生年齡都大於的班級對象

  from Group g where <all  (select sage from gstudents s)

  下列語句返回在所有學生中有一個學生的年齡等於的班級

  from Group g where = any (select sage from gstudents s)

  或者

  from Group g where = some(select sage from gstudents s)

  或者

  from Group g where in (select sage from gstudents s)

  order by子句

  查詢返回列表可以按照任何返回的類或者組件的屬性排序

  from Student s order by sname asc

  連接查詢

  與SQL一樣HQL也支持連接查詢如內連接外連接和交叉連接

  inner join內連接

  left outer join左外連接

  rigth outer join右外連接

  full join全連接但不常用

  下面我重點介紹下內連接查詢左外連接和或外連接和內連接大同小異而全連接幾乎沒有使用得到的地方

  inner join可以簡寫為join例如在查詢得到的Group對象時內連接取得對應的Student對象實現的程序代碼如下

  Student stu = null;

  Group group = null;

  Query query = sessioncreateQuery(from Group g join gstudents);

  List list = querylist();

  Object obj[] = null;

  for(int i = ; i < listsize(); i++)

  {

  obj = (Object[])listget(i);

  group = (Group)obj[];//group是數組是第一個對象

  stu = (Student)obj[];//stu是數組的第二個對象

  Systemoutprintln(stugetName()+屬於+groupgetName());

  }

  Criteria Query方式

  當查詢數據時往往需要設置查詢條件在SQL或HQL語句中查詢條件常常放在where子句中此處Hibernate還支持Criteria查詢這種查詢方式把查詢條件封裝為一個Criteria對象在實際應用中可以使用Session的createCriteria()方法構建一個orghibernateCriteria實例然後把具體的查詢條件通過Criteria的add方法加入到Criteria實例中這樣程序員可以在不使用SQL甚至HQL的情況下進行數據查詢如下     public void criteriaDEMO()

  {

  Session session = HibernateUtilcurrentSession();

  Criteria criteria = sessioncreateCriteria(TRegisterclass);//生成一個Criteria實例

  criteriaadd(Restrictionseq(userNamefengyan));//等價於where name = fengyan

  List list = criterialist();

  TRegister user = (TRegister)listget();

  Systemoutprintln(usergetUserName());

  }

  常用的查詢限制方法

  上面代碼中 Restrictionseq()方法表示equal即等於的情況Restrictions類提供了查詢限制機制它提供了許多方法以實現查詢限制

  Restrictionseq()equal=

  RestrictionsallEq() 參數為Map對象使用key/value進行多個等於的對比相當於多個                                          Restrictionseq()的效果

  Restrictionsgt()greaterthan<

  Restrictionslt()lessthan<

  Restrictionslelessequal<=

  Restrictionsbetween()對應SQL的between子句

  Restrictionslike()對應SQL的like子句

  Restrictionsin()對應SQL的in子句

  Restrictionsand()and 關系

  Restrictionsor()or 關系

  RestrictionsisNull()判斷屬性是否為空為空返回true否則返回false

  RestrictionsisNoyNull()與上面的相反

  Orderasc()根據傳入的字段進行升序排序

  Orderdesc()與上相反

  MatchModeEXACT字符串中精確匹配相當於like value

  MatchModeANYWHERE字符串在中間位置相當於like%value%

  MatchModeSTART字符串在最前面相當於likevalue%

  MatchModeEND字符串在最後相當於like%value

  下面是幾個查詢限制的例子

  查詢學生名字以t開關的所有Student對象

  Criteria criertia = sessioncreateCriteria(Studentclass);

  criteriaadd(Restrictionslike(name t%));

  List list = criterialist();

  Student stu = (Student)listget();

  或者

  Criteria criertia = sessioncreateCriteria(Studentclass);

  criteriaadd(Restrictionslike(name tMatchModeSTART));

  List list = criterialist();

  Student stu = (Student)listget();

  查詢學生姓名在BillJack和Tom之間所有的Student對象

  String[] names = {BillJackTom};

  Criteria criertia = sessioncreateCriteria(Studentclass);

  criteriaadd(Restrictionsin(name names));

  List list = criterialist();

  Student stu = (Student)listget();

  查詢學生年齡(age)等於或為空(null)的所有學生對象

  Criteria criertia = sessioncreateCriteria(Studentclass);

  criteriaadd(Restrictionseq(age new Integer()));

  criteriaadd(RestrictionsisNull(age));

  List list = criterialist();

  Student stu = (Student)listget();

  查詢學生姓名以字母F開頭的所有Student對象並按姓名升序排序

  Criteria criertia = sessioncreateCriteria(Studentclass);

  criteriaadd(Restrictionslike(name F%));

  criteriaaddOrder(Orderasc(name));

  List list = criterialist();

  Student stu = (Student)listget();

  注意調用Orderasc的方法應該是CriteriaaddOrder()方法

  連接限制

  Criteria查詢中使用FetchMode來實現連接限制在HQL語句中可以通過fetch關鍵字來表示預先抓取(Eager fetching)如下

  from Group g

  left join fetch gstudents s

  where gname like %

  可以使用Criteria的API完成同樣的功能如下

  Criteria criertia = sessioncreateCriteria(Groupclass);

  criteriasetFetchMode(students FetchModeEAGER);

  criteriaadd(Restrictionslike(name MatchModeEND));

  List list = criterialist();

  以上兩種方式編寫的代碼都使用相同的SQL語句來完成它們的功能如下

  select  g* s* from Group g

  left outer join Student s

  on gid = sgroup_id

  where gname like %

  Native SQL查詢

  本地SQL查詢指的是直接使用本地數據庫的SQL語言進行查詢這樣做對於將 原來的SQL/JDBC程序遷移到Hibernate應用很有用

  創建一個基於SQL的Query

  Native SQL查詢是通過SQLQuery接口來控制的它通過調用SessioncreateSQLQuery()方法來獲得

  String sql = select {s*} from t_student s where sage>;

  //{}用來引用數據表的別名{s*}表示使用s來做為t_student表的別名

  SQLQuery sqlQuery = sessioncreateSQLQuery(sql);

  sqlQueryaddEntity(sStudentclass);

  List list = sqlQuerylist();

  for(int i = ; i < listsize(); i++)

  {

  Student stu = (Student)listget(i);

  }

  //createSQLQuery(String sql)利用傳入的sql參數構造一個SQLQuery實例使用該方法時還需要傳入查詢的實體類因此在配合使用SQLQuery的addEntity()方法一起使用

  命名SQL查詢

  與HQL的命名查詢相似也可以將 本地的SQK查詢語句定義在映射文件中然後像調用一個命名HQL查詢一樣專題報道調用命名SQL查詢

  如   </class>

  <sqlquery name=QueryStudents>

  <![CDATA[

  select {s*} from t_student s where sage >

  ]]>

  <return alias=s class=Student />

  </sqlquery>

  </hibernatemapping>配合以上配置我們可以如下編寫代碼來查詢 Query query = sessiongetNamedQuery(QueryStudents);

  List list = querylist();

  for(int i = ; i < listsize();i++)

  {

  Student stu = (Student)listget(i);

  }

  也可以在命名查詢是設定參數如下  <sqlquery name=QueryStudents>

  <![CDATA[

  select {s*} from t_student s where sage > :age

  ]]>

  <return alias=s class=Student />

  </sqlquery>

  </hibernatemapping>程序代碼 Query query = sessiongetNamedQuery(QueryStudents);

  querysetInteger(age);

  List list = querylist();

  for(int i = ; i < listsize();i++)

  {

  Student stu = (Student)listget(i);

  }自定義insert update和delete語句

  Hibernate x的映射文件中新添加<sql_insert><sql_update><sqldelete>個標記可以使用這個標記自定義自己的insert updatedelete語句 </class>

  <sqlinsert>

  insert into t_student(nameageid) values(???)

  </sqlinsert>

  <sqlupdate>

  update t_student set name=?age=? where id=?

  </sqlupdate>

  <sqldelete>

  delete from t_student where id = ?

  </sqldelete>

  </hibernatemapping>對於以上自定義的SQL語句要注意以下幾點

  insert 和update語句中定義的字段必須和映射文件聲明的屬性相應一個都不能少

  在insert 和update語句中屬性出現的順序必須和映射文件中的順序一樣

  在insert語句中主鍵id總是放在最後

  在程序中實現以上自定義的insert語句如下 Student stu = new Student();

  stusetName(Bill);

  stusetAge();

  sessionsave(stu);如果不想在insert或update語句中包括所有屬性則可以在屬性定義時 加上insert =false或update=false如下 <property name = name type=string insert = false update=false/>

  <sqlinsert>

  insert into t_student(ageid) values(??)

  </sqlinert>


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26346.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.