1. 程式人生 > >2018-03-12 Hibernate練習筆記

2018-03-12 Hibernate練習筆記

2018-03-12 hibernate練習

在使用hibernate的HQL查詢的時候 注意 from 後面的表明為實體類的名稱 切區分大小寫!!! 且不支援select * from Student這樣的查詢方式
    String hql = "select id from Student where id = 2";  =======>>> 這裡的Student 即為對應的實體類 不是表名 !!!
    Query query = session.createQuery(hql);
    Object stu = query.uniqueResult();

hibernate支援別名方式設定引數

Session session = sf.openSession();
String hql = "select id from Student where name = :name";
Query<Object> query = session.createQuery(hql);
query.setParameter("name", "xiaohua");
Integer i = (Integer) query.uniqueResult();  // 這裡注意uniqueResult 無法自動包裝
System.out.println(i);

hibernate 支援佔位符設定引數

Session session = sf.openSession();
String hql = "select id,name,sex,birth,des from Student where name = ?";
Query query = session.createQuery(hql);
query.setParameter(0, "xiaohua");
List list = query.list();

這裡要注意  query.list()
java.lang.ClassCastException:
[Ljava.lang.Object; cannot be cast to bean.PersonStatis居然不能轉換。

通過多方驗證,這個返回的List中並不是存放的是Student物件,而是存放的查詢出來對應於欄位順序的一個數組物件。
於是我們需要通過Object[] obj = list.get(0);然後在根據相應的陣列下標取得相應的值
Object[] arr = (Object[]) list.get(0);
System.out.println(arr[0] +"-" +arr[1]);

如果HQL 中不新增要查詢的欄位(即去掉 select xxx )則不會出現上述的異常!
    Session session = sf.openSession();
    String hql = "from Student";  ==> 這裡去掉了 select子句
    Query<Student> query = session.createQuery(hql);
    List<Student> list = query.list();
    for (Student s : list){
        System.out.println(s);
    }

HQL也支援 自定義返回型別 同時要注意這裡的 new Student(id,name,sex) 對應 Student實體類中的構造器!!!
    String hql = "select new Student(id,name,sex) from Student";
    Query<Student> query = session.createQuery(hql);
    List<Student> list = query.list();
    for (Student s : list){
        System.out.println(s);
    }

    返回Map型別  注意下面兩種不同的HQL語句 所查出來的結果的查詢方式不同!!!
    Session session = sf.openSession();
    String hql = "select new map(id,name) from Student";
    String hql2 = "select new map(id as id,name as name) from Student";
    Query<Map> query = session.createQuery(hql);
    Query<Map> query2 = session.createQuery(hql2);
    List<Map> list = query.list();
    List<Map> list2 = query2.list();
    for (Map m : list){
        System.out.println(m.get("0") +"---"+ m.get("1"));
    }
    for (Map m : list){
        System.out.println(m.get("id") +"---"+ m.get("name"));
    }


HQL總結
1、沒有select子句有from子句的HQL查詢,查詢表格的記錄,返回的物件是查詢類物件;即List<查詢類名> list=query.list();

2、有select子句的HQL查詢,查詢表格記錄,返回的物件是Object[]類物件,即List<Object[]> lsit=query.lsit();

3、我們可以通過在HQL語句中使用new list(...),new map(...),new Students2(...)的方式來指定查詢返回的物件型別。

4、使用new Students2(...)的方式,即以自定義型別返回的方式,需要在該查詢類的持久化類Students2.java中新增相應的建構函式



QBC查詢


QBE查詢


hibernate 快取機制

一級快取
Hibernate的一級快取由Session提供,只存在於Session的生命週期中,當應用程式呼叫Session介面的
save(),update(),saveOrupDate(),get(),load()或者Query和Criteria例項的list(),iterate()等方法時
如果Session快取中沒有相應的物件,hibernate就會把物件加入到一級快取中,當session關閉時,該Session所管理的一級快取也會立即被清除;

hibernate 清理一級快取的時機

    (1)呼叫 事務的commit()方法時會自動清理快取

    (2)呼叫query 查詢物件時 如果物件的屬性發生了變化 則會自動清理快取

    (3)顯示呼叫session.flush()時會自動清理快取

    (4)關閉session時 清理快取

一級快取由session(輕量級,執行緒不安全單位)提供  所以一般生命週期為一個事務的生命週期 事務開始開啟 事務提交被關閉

二級快取由sessionFactory (重量級,執行緒安全單位)提供 所以一般生命的週期為程序獲取群集的週期

Hibernate java物件的三態變化
臨時態 <—> 持久態 <—> 遊離態

臨時態 ===> 持久態 save() saveOrUpdate() 此時不存在session快取中,資料庫中也沒有對應的記錄

持久態 ===> 遊離態 evict() clear() close()
遊離態,持久態 ===> 臨時態 delete()

遊離態 ===> 持久態 update() saveOrUpdate() lock()

Hibernate 執行原理