Hibernate中HQL語句

HQL: Hibernate Query Language, 一個純面向對象的查詢語言. 其語法中對語法關鍵字大小寫不敏感, 這種特性與SQL語言類似.其整體結構也與SQL語言類似.
基本規則
1. HQL語法類似於SQL,也是一種select from結構的語句。但是他後面跟的不是表名和字段名,而是類名和屬性名。
2. HQL基本查詢語法跟SQL很類似
3. HQL大小寫不敏感。但是,設計java類名、包名、屬性名時大小寫敏感。
4. 包名的使用情況。比如:如果註冊的實體類Emp只有一個唯一的類,那麼查詢時可以不加包名,hibernate會自動檢索到Emp類。但是如果註冊多個實體類,名字都叫Emp。此時就要增加包名來區別多個實體類。


下面一些簡單的案例來使用簡單HQL語法

@Test
public void test() {
    /**
     * 採用HQL語句,後面寫的是對象名
     * sql : select * from tb_student;
     * hql : from Student; 
     * 注意:
     * 類名和屬性名區分大小寫
     * 語法結構和sql類似
     */
    //編寫HQL語句
    String hql = "from Student";
    //創建query對象
    Query query = session.createQuery(hql);
    //執行查詢
    System.out.println("使用List集合查詢");
    List<Student> list = query.list();
    for (Student student : list) {
        System.out.println(student);
    }
    /*
     * list方法和iterate方法的區別
     * list發出一條sql語句,查詢全部數據
     * iterate發出一條sql語句,查詢符合條件的id
     * 當使用到對象就根據id查詢此對象,發出另一條sql語句
     * list會把數據存儲到緩存中,但它不會利用緩存,每次都從數據庫中查詢
     * iterate則會利用緩存(先查詢符合條件的id,再根據id去緩存中查找對象,如果緩存中有此對象,則直接從緩存中取出此對象)
     * 
     * 應用場景:
     * list:數據量較小,數據是財務或實時數據
     *      相反則使用iterate
     */
    System.out.println("使用Iterate迭代器查詢");
    Iterator iterate = query.iterate();
    while(iterate.hasNext()){
        Student stu = (Student) iterate.next();
        System.out.println(stu);
    }
}

根據id查詢學生-返回的是一個學生對象

@Test
public void getStudentById(){
    String hql = "from Student where sid=1";
    Query query = session.createQuery(hql);
    Student stu = (Student) query.uniqueResult();
    System.out.println(stu);
}

查詢學生總人數-返回的是一條數據

@Test
public void getStudentCount(){
    String hql = "select  count(s) from Student s";
    Query query = session.createQuery(hql);
    long stu = (long) query.uniqueResult();
    System.out.println(stu);
}

查詢已成年的女學生-帶條件

@Test
public void getStudentByWhere(){
    String hql = "select  count(s) from Student s where age>=16 and gender='女'";
    Query query = session.createQuery(hql);
    long stu = (long) query.uniqueResult();
    System.out.println(stu);
}

查詢學生的名字和年齡-返回的集合爲list

@Test
public void getStudentByPro(){
    String hql = "select sname,age,birthday from Student";
    Query query = session.createQuery(hql);
    List<Object[]> list = query.list();
    for (Object[] object : list) {
        System.out.println("姓名:"+object[0]+"---年齡:"+object[1]+"---生日:"+object[2]);

    }
    hql = "select sname from Student";
    query = session.createQuery(hql);
    List<Object> list2 = query.list();
    for (Object object : list2) {
        System.out.println("姓名:"+object);

    }
}

可以封裝返回的屬性
需要提供相應的構造方法
還要注意參數順序

@Test
public void getStudentByPro2(){
    String hql = "select new Student(sname,age,birthday) from Student";
    Query query = session.createQuery(hql);
    List<Student> list = query.list();
    for (Student stu : list) {
        System.out.println(stu);
    }
}

採用佔用符?
查詢條件爲18-30之間的學生

@Test
public void getStudentByPro3(){
    String hql = "select new Student(sname,age) from Student where age between ? and ?";
    Query query = session.createQuery(hql);
    //設置參數,從0開始。允許鏈式編程
    query.setInteger(-0, 18).setInteger(1, 30);
    //當不清楚設置的屬性類型時,可以用setParameter
    query.setParameter(0, 18).setParameter(1, 30);

    List<Student> list = query.list();
    for (Student stu : list) {
        System.out.println(stu);
    }
}

命名參數
:名稱

@Test
public void getStudentByPro4(){
    String hql = "from Student where (age between :minage and :maxage) and sname like :ben";
    Query query = session.createQuery(hql);
    //當不清楚設置的屬性類型時,可以用setParameter
    query.setParameter("minage", 18).setParameter("maxage", 30).setParameter("ben", "ben%");

    List<Student> list = query.list();
    for (Student stu : list) {
        System.out.println(stu);
    }
}

命名參數
:名稱
可以把參數存放進Map中

@Test
public void getStudentByFlag1(){
    String hql = "from Student where (age between :minage and :maxage) and sname like :ben";
    Query query = session.createQuery(hql);
    Map<String,Object> map = new HashMap<>();
    map.put("minage", 18);
    map.put("maxage", 30);
    map.put("ben", "ben%");
    query.setProperties(map);
    List<Student> list = query.list();
    for (Student stu : list) {
        System.out.println(stu);
    }
}

聚合函數

查詢學生的總人數,平均年齡 最大年齡

@Test
public void getFun(){
    String hql = "select count(s),avg(age),max(age) from Student s";
    Query query = session.createQuery(hql);
    Object[] object = (Object[]) query.uniqueResult();
    System.out.println("總人數:"+object[0]+"---平均年齡:"+object[1]+"---最大年齡:"+object[2]);
}

根據學生的性別分組,顯示 :性別,人數
返回的是一個集合,需要使用List

@Test
public void getFun2(){
    String hql = "select gender,count(*) from Student group by gender";
    Query query = session.createQuery(hql);
    List<Object[]> list =  (List<Object[]>) query.list();
    for (Object[] object : list) {
        System.out.println("性別:"+object[0]+"---人數:"+object[1]);
    }
}

查詢就讀java班級的學生

@Test
public void getFun3(){
    String hql = "select s from Student s,Course c where c.cid=s.sid and c.cname='java'";
    Query query = session.createQuery(hql);
    List<Student> list =  query.list();
    for (Student stu : list) {
        System.out.println(stu.toString());
    }
}

數據分頁
一頁顯示5條數據

@Test
public void listPage(){
    String hql = "from Student";
    Query query = session.createQuery(hql);
    /*
     * mysql中使用limit 0,5
     * oracle中使用rownum僞列
     * 設置分頁的參數:setFirstResult開始行
     *           setMaxResults查詢數量
     */
    query.setFirstResult(0);
    query.setMaxResults(5);
    List<Student> list = query.list();
    for (Student student : list) {
        System.out.println(student);
    }
}

/**
* 連接查詢
* 內連接:2張表中所有滿足條件的數據
* SQL:select * from A a,B b where a.id=b.id;
* select * from A a join B b on a.id=b.id;
* 外連接:
* 左外連接:查詢左表中所有符合條件的數據,右表中沒有則返回null
* SQL:select * from A a left join B b on a.id=b.id;
* 右外連接:和左外連接相反
* 全連接
*/

全連接

@Test
public void getTables(){
    String hql = "select s.sname,c.cname from Student s join s.courseset c";
    Query query = session.createQuery(hql);
    List<Object[]> list = query.list();
    for (Object[] student : list) {
        System.out.println(student[0]+"---"+student[1]);
    }
}

左外連接

@Test
public void getTables2(){
    String hql = "select s.sname,c.cname from Student s left join s.courseset c";
    Query query = session.createQuery(hql);
    List<Object[]> list = query.list();
    for (Object[] student : list) {
        System.out.println(student[0]+"---"+student[1]);
    }
}

右外鏈接

@Test
public void getTables3(){
    String hql = "select s.sname,c.cname from Student s right join s.courseset c";
    Query query = session.createQuery(hql);
    List<Object[]> list = query.list();
    for (Object[] student : list) {
        System.out.println(student[0]+"---"+student[1]);
    }
}

注意:在進行雙向通信時,兩個對象的toString方法不能互相返回對方的集合對象

xml文件中配置:

    </class>
    <!-- 定義HQL -->
    <query name="queryall">
        from Student
    </query>
</hibernate-mapping>

//外部命名查詢(hql語句在任何一個有效的映射文件中定義,並給定名稱,應用通過給定名稱查詢

@Test
public void getStudentByHbm(){
    Query query = session.getNamedQuery("queryall");
    List<Student> list = query.list();
    for (Student student : list) {
        System.out.println(student);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章