歡迎您光臨本站 註冊首頁

Hibernate數據查詢

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  Hibernate Query Language(HQL)

  Criteria Query

  Native SQL

  下面對其分別進行解釋

  Hibernate Query Language:

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

  from子句:

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

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

  select子句:

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

  例: public void HQLselectDEMO()

  {

  TRegister user = new TRegister();

  Session session = HibernateUtil.currentSession();

  Query query = session.createQuery("select u.userName from TRegister u");

  List list = query.list();

  for(int i = 0 ; i < list.size(); i )

  {

  String name = (String)list.get(i);

  System.out.println(name);

  }

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

  {

  TRegister user = new TRegister();

  Session session = HibernateUtil.currentSession();

  Query query = session.createQuery("select u.userName ,u.sex from TRegister u");

  List list = query.list();

  for(int i = 0 ; i < list.size(); i )

  {

  Object obj[] = (Object[])list.get(i);

  System.out.println(obj[0] " 的性別是:" obj[1]);

  }

  }

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

  {

  Session session = HibernateUtil.currentSession();

  Query query = session.createQuery("select new TRegister(u.userName,u.sex) from TRegister u");

  List list = query.list();

  for(int i = 0 ; i < list.size(); i )

  {

  //Object obj[] = (Object[])list.get(i);

  TRegister user = (TRegister)list.get(i);

  System.out.println(user.getUserName() " 的性別是:" user.getSex());

  }

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

  public TRegister(String userName,String sex) {

  this.userName = userName;

  this.sex = sex;

  }

  */

  }

  統計函數查詢

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

  count():統計記錄條數.

  min():求最小值.

  max():求最大值.

  sum():求和.

  avg():求平均值.

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

  select count(*) from Student

  取得Student平均年齡的HQL語句:

  select avg(s.age) from Student as s

  可以使用distinct去除重複的數據:

  select distinct s.age from Student as s

  where子句:

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

  Query query = session.createQuery("from Student as s where s.name='Bill'");

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

  數學操作: ,-,*,/

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

  邏輯操作:and ,or, not

  字元串連接:||

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

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

  all:表示所有的記錄.

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

  some:與any相同.

  in:與any等價.

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

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

  from Group g where 18<all (select s.age from g.students s)

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

  from Group g where 22 = any (select s.age from g.students s)

  或者

  from Group g where 22= some(select s.age from g.students s)

  或者

  from Group g where 22 in (select s.age from g.students s)

  order by子句

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

  from Student s order by s.name 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 = session.createQuery("from Group g join g.students");

  List list = query.list();

  Object obj[] = null;

  for(int i = 0 ; i < list.size(); i )

  {

  obj = (Object[])list.get(i);

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

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

  System.out.println(stu.getName() "屬於" group.getName());

  }

  Criteria Query方式

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

  {

  Session session = HibernateUtil.currentSession();

  Criteria criteria = session.createCriteria(TRegister.class);//生成一個Criteria實例

  criteria.add(Restrictions.eq("userName","fengyan"));//等價於where name = 'fengyan'

  List list = criteria.list();

  TRegister user = (TRegister)list.get(0);

  System.out.println(user.getUserName());

  }

  常用的查詢限制方法

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

  Restrictions.eq():equal,=

  Restrictions.allEq(): 參數為Map對象,使用key/value進行多個等於的對比,相當於多個 Restrictions.eq()的效果

  Restrictions.gt():greater-than,<

  Restrictions.lt():less-than,<

  Restrictions.le:less-equal,<=

  Restrictions.between():對應SQL的between子句.

  Restrictions.like():對應SQL的like子句.

  Restrictions.in():對應SQL的in子句.

  Restrictions.and():and 關係.

  Restrictions.or():or 關係.

  Restrictions.isNull():判斷屬性是否為空,為空返回true,否則返回false.

  Restrictions.isNoyNull():與上面的相反.

  Order.asc():根據傳入的欄位進行升序排序.

  Order.desc():與上相反

  MatchMode.EXACT:字元串中精確匹配,相當於like 'value'

  MatchMode.ANYWHERE:字元串在中間位置,相當於like'%value%'

  MatchMode.START:字元串在最前面,相當於like'value%'

  MatchMode.END:字元串在,相當於like'%value'

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

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

  Criteria criertia = session.createCriteria(Student.class);

  criteria.add(Restrictions.like("name", "t%"));

  List list = criteria.list();

  Student stu = (Student)list.get(0);

  或者:

  Criteria criertia = session.createCriteria(Student.class);

  criteria.add(Restrictions.like("name", "t",MatchMode.START));

  List list = criteria.list();

  Student stu = (Student)list.get(0);

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

  String[] names = {"Bill","Jack","Tom"};

  Criteria criertia = session.createCriteria(Student.class);

  criteria.add(Restrictions.in("name", names));

  List list = criteria.list();

  Student stu = (Student)list.get(0);

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

  Criteria criertia = session.createCriteria(Student.class);

  criteria.add(Restrictions.eq("age", new Integer(22)));

  criteria.add(Restrictions.isNull("age"));

  List list = criteria.list();

  Student stu = (Student)list.get(0);

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

  Criteria criertia = session.createCriteria(Student.class);

  criteria.add(Restrictions.like("name", "F%"));

  criteria.addOrder(Order.asc("name"));

  List list = criteria.list();

  Student stu = (Student)list.get(0);

  注意調用Order.asc的方法應該是Criteria.addOrder()方法.

  連接限制

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

  from Group g

  left join fetch g.students s

  where g.name like ' 05'

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

  Criteria criertia = session.createCriteria(Group.class);

  criteria.setFetchMode("students", FetchMode.EAGER);

  criteria.add(Restrictions.like("name", "2005",MatchMode.END));

  List list = criteria.list();

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

  select g.*, s.* from Group g

  left outer join Student s

  on g.id = s.group_id

  where g.name like ' 05'

  Native SQL查詢

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

  創建一個基於SQL的Query

  Native SQL查詢是通過SQLQuery介面來控制的,它通過調用Session.createSQLQuery()方法來獲得.如:

  String sql = "select {s.*} from t_student s where s.age>22";

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

  SQLQuery sqlQuery = session.createSQLQuery(sql);

  sqlQuery.addEntity("s",Student.class);

  List list = sqlQuery.list();

  for(int i = 0 ; i < list.size(); i )

  {

  Student stu = (Student)list.get(i);

  }

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

  命名SQL查詢

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

  如: </class>

  <sql-query name="QueryStudents">

  <![CDATA[

  select {s.*} from t_student s where s.age > 22

  ]]>

  <return alias="s" class="Student" />

  </sql-query>

  </hibernate-mapping>配合以上配置我們可以如下編寫代碼來查詢 Query query = session.getNamedQuery("QueryStudents");

  List list = query.list();

  for(int i = 0 ; i < list.size();i )

  {

  Student stu = (Student)list.get(i);

  }

也可以在命名查詢是設定參數,如下: <sql-query name="QueryStudents">

  <![CDATA[

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

  ]]>

  <return alias="s" class="Student" />

  </sql-query>

  </hibernate-mapping>程序代碼: Query query = session.getNamedQuery("QueryStudents");

  query.setInteger("age",22);

  List list = query.list();

  for(int i = 0 ; i < list.size();i )

  {

  Student stu = (Student)list.get(i);

  }自定義insert , update和delete語句:

  Hibernate 3.x的映射文件中新添加<sql_insert>,<sql_update>,<sql-delete>3個標記.可以使用這3個標記自定義自己的insert ,update,delete語句,如: </class>

  <sql-insert>

  insert into t_student(name,age,id) values(?,?,?)

  </sql-insert>

  <sql-update>

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

  </sql-update>

  <sql-delete>

  delete from t_student where id = ?

  </sql-delete>

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

  1:insert 和update語句中定義的欄位必須和映射文件聲明的屬性相應,一個都不能少.

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

  3:在insert語句中,主鍵id總是放在.

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

  stu.setName("Bill");

  stu.setAge(22);

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

  <sql-insert>

  insert into t_student(age,id) values(?,?)

  </sql-inert>


[火星人 ] Hibernate數據查詢已經有1099次圍觀

http://coctec.com/docs/java/show-post-60828.html