Hibernate3 一級緩存
1 對象狀態與一級緩存
1.1 狀態介紹
l hibernate 規定三種狀態:瞬時態、持久態、脫管態
l 狀態
瞬時態:transient,session沒有緩存對象,數據庫也沒有對應記錄。
OID特點:沒有值
持久態:persistent,session緩存對象,數據庫最終會有記錄。(事務沒有提交)
OID特點:有值
脫管態:detached,session沒有緩存對象,數據庫有記錄。
OID特點:有值
1.2 轉換
1.2.1 瞬時態/臨時態
l 獲得:一般都只直接創建(new)
l 瞬時態 轉換 持久態
一般操作:save方法、saveOrUpdate
l 瞬時態 轉換 脫管態
一般操作:通過setId
例如:
User user = new User(); //瞬時態
user.setUid(1); //脫管態
1.2.2 持久態
l 獲得:
查詢操作:get、loat、createQuery、createCriteria 等 獲得都是持久態【】
執行save之後持久態
執行update之後持久態
l 持久態 轉換 瞬時態
官方規定執行delete() --民間:刪除態
l 持久態 轉換 脫管態
session沒有記錄
session.close () 關閉
session.clear() 清除所有
session.evict(obj) 清除指定的PO對象
1.2.3 脫管態/ 遊離態
l 獲得:
創建、並設置OID的
通過api獲得
l 脫管態 轉換 瞬時態
手動去除OID,設置成默認值
l 脫管態 轉換 持久態
一般操作:update()、saveOrUpdate
@Test public void demo01(){ User user = new User(); //瞬時態 user.setUsername("jack"); user.setPassword("1234"); //瞬時態(與oid沒有關系)
Session session = factory.openSession(); session.beginTransaction();
session.save(user); //持久態 //---- 持久態就應該有持久態的行為(特性)
// user.setUsername("rose"); //持久態對象 被修改後,hibernate將自動生成update語句 // session.flush();
session.getTransaction().commit(); session.close();
System.out.println(user); //脫管態 } |
2 一級緩存
2.1 介紹
l 一級緩存:又稱為session級別的緩存。當獲得一次會話(session),hibernate在session中創建多個集合(map),用於存放操作數據(PO對象),為程序優化服務,如果之後需要相應的數據,hibernate優先從session緩存中獲取,如果有就使用;如果沒有再查詢數據庫。當session關閉時,一級緩存銷毀。
2.2 一級緩存操作
2.2.1 證明一級緩存
@Test public void demo02(){ //證明一級緩存 Session session = factory.openSession(); session.beginTransaction();
//1 查詢 id = 1 User user = (User) session.get(User.class, 1); System.out.println(user); //2 再查詢 -- 不執行select語句,將從一級緩存獲得 User user2 = (User) session.get(User.class, 1); System.out.println(user2);
session.getTransaction().commit(); session.close(); } |
2.2.2 移除
@Test public void demo03(){ //清除緩存 Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 1); //--select System.out.println(user);
//清除 //session.clear(); session.evict(user);
// 一級緩存沒有緩存對象,從數據庫直接查詢 User user2 = (User) session.get(User.class, 1); //--select System.out.println(user2);
session.getTransaction().commit(); session.close(); } |
2.2.3 一級緩存快照【掌握】
l 快照:與一級緩存一樣的存放位置,對一級緩存數據備份。保證數據庫的數據與 一級緩存的數據必須一致。如果一級緩存修改了,在執行commit提交時,將自動刷新一級緩存,執行update語句,將一級緩存的數據更新到數據庫。
2.2.4 refresh 刷新
l refresh 保證 一級緩存的數據 與 數據庫的數據 保持一致。將執行select語句查詢數據庫,將一級緩存中的數據覆蓋掉。只要執行refresh都將執行select語句。
@Test public void demo04(){ //刷新 Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 1); //--select System.out.println(user);
session.refresh(user);
session.getTransaction().commit(); session.close(); } |
2.2.5 快照演示(一級緩存刷新)
@Test public void demo05(){ //快照 Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 1); //--select System.out.println(user);
//修改持久態對象內容(一級緩存內容)--默認在commit時,將觸發update語句。 user.setUsername("rose2");
session.getTransaction().commit(); session.close(); } |
l 問題:一級緩存什麽時候刷新?(了解)
默認情況提交(commit())刷新。
@Test public void demo06(){ //設置刷新時機 Session session = factory.openSession(); session.beginTransaction();
//1 設置 session.setFlushMode(FlushMode.MANUAL);
User user = (User) session.get(User.class, 1); user.setUsername("rose4");
//1 查詢所有 -- AUTO , 查詢之前先更新,保存一級緩存和數據庫一樣的 //List<User> allUser = session.createQuery("from User").list();
//2手動刷新 --MANUAL 將執行update,註意:一級緩存必須修改後的 session.flush();
// 如果MANUAL 在執行commit 不進行update session.getTransaction().commit(); session.close(); } |
2.3 PO對象操作
2.3.1 save & persist
l save方法:瞬時態 轉換 持久態 ,會初始化OID
1.執行save方法,立即觸發insert語句,從數據庫獲得主鍵的值(OID值)
2.執行save方法前,設置OID將忽略。
3.如果執行查詢,session緩存移除了,在執行save方法,將執行insert
@Test public void demo01(){ User user = new User(); user.setUid(100); user.setUsername("jack"); user.setPassword("1234");
Session session = factory.openSession(); session.beginTransaction();
session.save(user);
session.getTransaction().commit(); session.close(); } |
@Test public void demo03(){ //代理 assigned User user = new User(); //user.setUid(100); user.setUsername("jack"); user.setPassword("1234");
Session session = factory.openSession(); session.beginTransaction();
session.save(user);
session.getTransaction().commit(); session.close(); } |
l 註意:持久態對象不能修改OID的值
@Test public void demo04(){
Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 100); user.setUid(101);
session.save(user);
session.getTransaction().commit(); session.close(); } |
l persist方法:瞬時態 轉換 持久態 ,不會立即初始化OID
註意: persist方法不會立即得到ID,所以執行sql語句的時機要靠後.
2.3.2 update
l update:脫管態 轉換 持久態
如果OID在數據存放的,將執行update語句
如果OID不存在將拋異常
@Test public void demo01(){ //自然 assigned User user = new User(); user.setUid(101); user.setUsername("jack1"); user.setPassword("12345");
Session session = factory.openSession(); session.beginTransaction();
session.update(user);
session.getTransaction().commit(); session.close(); } |
l 註意1:如果數據沒有修改,執行save方法,將觸發update語句。
查詢速度 比 更新速度快
通過<class select-before-update> 來設置更新前先查詢,如果沒有改變就不更新。
總結:
update 之後對象 持久態
@Test public void demo03(){ // merge 合並 User user = new User(); user.setUid(1); user.setUsername("jack3"); user.setPassword("12345");
Session session = factory.openSession(); session.beginTransaction();
// 1 oid =1 持久態對象 User user2 = (User) session.get(User.class, 1);
// session.update(user); session.merge(user);
session.getTransaction().commit(); session.close(); } |
2.3.3 saveOrUpdate
l 代理主鍵:
判斷是否有OID
如果沒有OID,將執行insert語句
如果有OID,將執行update語句。
@Test public void demo02(){ // 代理 native User user = new User(); // user.setUid(2); user.setUsername("jack2"); user.setPassword("12345");
Session session = factory.openSession(); session.beginTransaction();
session.saveOrUpdate(user);
session.getTransaction().commit(); session.close(); } |
l 自然主鍵:
先執行select語句,查詢是否存放
如果不存在,將執行insert
如果存在,將執行update
@Test public void demo02(){ // 自然 assigned User user = new User(); user.setUid(2); user.setUsername("jack2333"); user.setPassword("12345333");
Session session = factory.openSession(); session.beginTransaction();
session.saveOrUpdate(user);
session.getTransaction().commit(); session.close(); } |
l 註意1:native下,默認OID是否存在,使用默認值。例如:Integer 默認null
通過<id unsaved-value="1"> 修改使用默認值,如果設置1進行insert語句。此內容提供hibernate使用的,錄入到數據庫後,采用自動增長。
2.3.4 delete
總結:
PO對象狀態:瞬時態、持久態、脫管態
Hibernate3 一級緩存