Hibernate數據查詢(轉)

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);
        }
    }

若是要查詢兩個以上的屬性檜以數組的方式返回,以下:sql

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)session

order by子句
查詢返回列表能夠按照任何返回的類或者組件的屬性排序
from Student s order by s.name ascapp

鏈接查詢
與SQL同樣,HQL也支持鏈接查詢,如內鏈接,外鏈接和交叉鏈接:
inner join:內鏈接
left outer join:左外鏈接
rigth outer join:右外鏈接
full join:全鏈接,但不經常使用
下面我重點介紹下內鏈接查詢,左外鏈接和或外鏈接和內鏈接大同小異,而全鏈接幾乎沒有使用獲得的地方。
inner join能夠簡寫爲join,例如在查詢獲得的Group對象時,內鏈接取得對應的Student對象,實現的程序代碼以下:less

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()方法。fetch

鏈接限制
Criteria查詢中使用FetchMode來實現鏈接限制。在HQL語句中,能夠經過fetch關鍵字來表示預先抓取(Eager fetching),以下:
from Group g 
left join fetch g.students s
where g.name like '%2005'
可使用Criteria的API完成一樣的功能,以下:this

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 '%2005'

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>
相關文章
相關標籤/搜索