HQL是個中立的語言,即它跟任何數據庫都沒關系,你如果使用HQL的話通過數據庫方言都會翻譯成相應的數據庫的SQL語句,包括[排序,子查詢,調用SQL中的函數].
  HQL中關鍵字是不區分大小寫的,但是屬性和類型是區分大小寫的。
   1>.簡單屬性查詢
      1>).單一屬性查詢,返回結果集屬性列表,元素類型和實體類中相應的屬性類型一致。如:
          session = HibernateUtils.getSession();
          session.beginTransaction();
           
          //返回結果集屬性列表,元素類型和實體類中相應的屬性類型一致
           List students = session.createQuery("select name from Student").list();
           for (Iterator iter=students.iterator(); iter.hasNext();) {
                  String name = (String)iter.next();
                  System.out.println(name);
           }
      session.getTransaction().commit();
      2>).多個屬性查詢,返回的集合元素是對象數組,數組元素的類型和對
          應的屬性在實體類中的類型一致,數組的長度取決于select中屬性的個數。如:
          List students = session.createQuery("select id, name from Student").list();
         for (Iterator iter=students.iterator(); iter.hasNext();) {
                Object[] obj = (Object[])iter.next();
                System.out.println(obj[0] + "," + obj[1]);
          }
      3>).如果認為返回數組不夠對象化,可以采用HQL動態實例化Student對象,
          但是Strudent類中必須提供相應的構造函數。如:
          List students = session.createQuery("select new Student(id, name) from Student").list();
          for (Iterator iter=students.iterator(); iter.hasNext();) {
                Student student = (Student)iter.next();
                System.out.println(student.getId() + "," + student.getName());
          }
    2>.實體對象查詢
       1>).返回Student對象的集合,可以忽略select,表可以使用別名,別名可以用as也可以不用。如:
          List students = session.createQuery("from Student s").list();
          //List students = session.createQuery("from Student as s").list();
         for (Iterator iter=students.iterator(); iter.hasNext();) {
                 Student student = (Student)iter.next();
                 System.out.println(student.getName());
           }
       2>).返回Student對象的集合,使用select查詢實體對象,必須采用別名。如:
          List students = session.createQuery("select s from Student as s").list();
          for (Iterator iter=students.iterator(); iter.hasNext();) {
                Student student = (Student)iter.next();
                 System.out.println(student.getName());
          }
       3>).不支持select * from .....這樣的查詢語句。如:下面的語句是錯誤的
           List students = session.createQuery("select * from Student").list();
       4>).list和iterator的區別?
           我們知道,session.createQuery()得到個Query,而從Hibernate API中我們可
           以發現Query有兩個方法list()和iterator()用于返回結果集。它們的區別在
           于:
           *list每次都會發出sql語句,list會向緩存中放入數據,而不利用緩存中的數據
           *iterator在默認情況下利用緩存數據,但如果緩存中不存在數據有可能出現N+1問題
        5>).N+1問題
            在默認情況下,使用query.iterator()查詢,有可能出現N+1問題
            1: 首先發出一條查詢對象id列表的sql語句
            N: 根據id列表到緩存中查詢,如果緩存中不存在與之匹配的數據,那么會根據
               id發出相應的sql語句
            如:
            Iterator iter = session.createQuery("from Student").iterate();
        while(iter.hasNext()) {
            Student student = (Student)iter.next();
            System.out.println(student.getName());
        }
    3>.條件查詢
       1>).可以采用拼字符串的方式傳遞參數。如:
               List students = session.createQuery("select s.id, s.name from Student s where s.name like '%1%'").list();
               for (Iterator iter=students.iterator(); iter.hasNext();) {
                      Object[] obj = (Object[])iter.next();
                       System.out.println(obj[0] + "," + obj[1]);
                }
       2>).可以使用?方式傳遞參數,參數的索引從0開始;傳遞的參數值如果是字符型的,不用
           單引號引起來;可以使用方法鏈編程。如:
            List students = session.createQuery("select s.id, s.name from Student s where s.name like ?")
                                                .setParameter(0, "%1%")
                                                .list();
           for (Iterator iter=students.iterator(); iter.hasNext();) {
                       Object[] obj = (Object[])iter.next();
                       System.out.println(obj[0] + "," + obj[1]);
           }
       3>).可以使用 :參數名稱 的方式傳遞參數值。如:
              List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname")
                                                   .setParameter("myname", "%1%")
                                                   .list();
              for (Iterator iter=students.iterator(); iter.hasNext();) {
                         Object[] obj = (Object[])iter.next();
                         System.out.println(obj[0] + "," + obj[1]);
             }
       4>).如果傳遞多個參數,可以使用setParameterList方法。如:
           List students = session.createQuery("select s.id, s.name from Student s where s.id in(:myids)")
                                                .setParameterList("myids", new Object[]{1, 2, 3, 4, 5})
                                               .list();
           for (Iterator iter=students.iterator(); iter.hasNext();) {
                   Object[] obj = (Object[])iter.next();
                   System.out.println(obj[0] + "," + obj[1]);
           }
       5>).在HQL中可以使用數據庫的函數,像mysql中的date_format。如:
             List students = session.createQuery("select s.id, s.name from Student s where date_format(s.createTime, '%Y-%m')=?")
                                                  .setParameter(0, "2008-02")
                                                  .list();
              for (Iterator iter=students.iterator(); iter.hasNext();) {
                     Object[] obj = (Object[])iter.next();
                      System.out.println(obj[0] + "," + obj[1]);
               }
       6>).查詢某個日期段的數據。如:
           SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
           //查詢2008-01-10到2008-02-15創建的學生
           List students = session.createQuery("select s.id, s.name from Student s where s.createTime between ? and ?")
                                               .setParameter(0, sdf.parse("2008-01-10 00:00:00"))
                                               .setParameter(1, sdf.parse("2008-02-15 23:59:59"))
                                               .list();
              for (Iterator iter=students.iterator(); iter.hasNext();) {
                     Object[] obj = (Object[])iter.next();
                      System.out.println(obj[0] + "," + obj[1]);
                }

    4>.Hibernate也支持直接使用sql查詢。如:
          List students = session.createSQLQuery("select * from t_student").list();
          for (Iterator iter=students.iterator(); iter.hasNext();) {
                Object[] obj = (Object[])iter.next();
                System.out.println(obj[0] + "," + obj[1]);
          }
    5>.外置命名查詢,主要完成hql語句和程序的解耦合.
       1>).在映射文件中采用<query>標簽來定義HQL語句。如:
            <query name="searchStudents">
                <![CDATA[
                      SELECT s FROM Student s where s.id<?
                 ]]>
            </query>
       2>).在程序中采用session.getNamedQuery()方法得到HQL查詢串。如:
              List students = session.getNamedQuery("searchStudents")
                                                   .setParameter(0, 10)
                                                   .list();
              for (Iterator iter=students.iterator(); iter.hasNext();) {
                     Student student = (Student)iter.next();
                     System.out.println(student.getName());
               }
     6>.查詢過濾器
       1>).在影射文件中定義過濾器參數。如:
        <filter-def name="filtertest">
                <filter-param name="myid" type="integer"/>
        </filter-def>   
       2>).在類的影射中使用這些參數。如:
         <filter name="filtertest" condition="id &lt; :myid"/><!--&lt;轉義字符"<"-->
       3>).在程序中啟用過濾器。如:
         session.enableFilter("filtertest")
                     .setParameter("myid", 10);   
         List students = session.createQuery("from Student").list();//會在該session中所有的查詢后自動加上過濾器中的條件
         for (Iterator iter=students.iterator(); iter.hasNext();) {
               Student student = (Student)iter.next();
               System.out.println(student.getName());
         }
       參見:Student.hbm.xml,FilterQueryTest.java
     7>.分頁查詢
        1>).setFirstResult()從0開始
        2>).setMaxResults每頁顯示多少條數據。如:
              List students = session.createQuery("from Student")
                                                   .setFirstResult(1)
                                                   .setMaxResults(2)
                                                   .list();
              for (Iterator iter=students.iterator(); iter.hasNext();) {
                     Student student = (Student)iter.next();
                     System.out.println(student.getName());
             }
     8>.對象導航查詢
        Hibernate支持對象的,因此可以用對象導航查詢。如:
        Student類總有Classes類型的屬性classes,而Classes類有name屬性。我們通過classes的name來查詢student:
        List students = session.createQuery("select s.name from Student s where s.classes.name like '%1%'").list();
        for (Iterator iter=students.iterator(); iter.hasNext();) {
             String name = (String)iter.next();
             System.out.println(name);
       }
     9>.連接查詢
        1>).內連接:只是把兩邊都有的記錄查出來,可以省略inner,并且只要影射文件中已經設好了表之間的關系,無須用on表示查詢條件。如:
           //List students = session.createQuery("select c.name, s.name from Student s join s.classes c").list();
           List students = session.createQuery("select c.name, s.name from Student s inner join s.classes c").list();
           for (Iterator iter=students.iterator(); iter.hasNext();) {
                Object[] obj = (Object[])iter.next();
                System.out.println(obj[0] + "," + obj[1]);
           }
        2>).外左連接:把左邊表的所有記錄都顯示出來。如:
             List students = session.createQuery("select c.name, s.name from Classes c left join c.students s").list();
             for (Iterator iter=students.iterator(); iter.hasNext();) {
                  Object[] obj = (Object[])iter.next();
                  System.out.println(obj[0] + "," + obj[1]);
             }
        3>).外右連接:把右邊表的所有記錄都顯示出來。如:
             List students = session.createQuery("select c.name, s.name from Classes c right join c.students s").list();
              for (Iterator iter=students.iterator(); iter.hasNext();) {
                   Object[] obj = (Object[])iter.next();
                   System.out.println(obj[0] + "," + obj[1]);
             }
     10>.統計查詢
        1>).count。如:
            Long count = (Long)session.createQuery("select count(*) from Student").uniqueResult();//返回的是單條記錄
            System.out.println(count);
        2>).group by。如:
            List students =session.createQuery("select c.name, count(s) from Student s join s.classes c " +
                    "group by c.name order by c.name").list();
           for (Iterator iter=students.iterator(); iter.hasNext();) {
                Object[] obj = (Object[])iter.next();
                System.out.println(obj[0] + ", " + obj[1]);
           }
     11>.DML風格的操作(盡量少用,因為緩存不同步)
        update和delete只會更新數據庫中的數據,而緩存中不會改,此時如果取得該數據還是緩存中的,而不會是更新后的,因此緩
        存中的數據就成了臟數據了。如果批量更新的話,還會給內存帶來很大壓力。如:
        session.createQuery("update Student s set s.name=? where s.id < ?")
                    .setParameter(0, "李四")
                    .setParameter(1, 5)
                    .executeUpdate();


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/yangfeitarena/archive/2009/04/17/4086334.aspx