1. 程式人生 > >Hibernate3 一級緩存

Hibernate3 一級緩存

tran lose amp 會話 方法 null mes ansi 情況

1 對象狀態與一級緩存

1.1 狀態介紹

l hibernate 規定三種狀態:瞬時態、持久態、脫管態

l 狀態

瞬時態:transientsession沒有緩存對象,數據庫也沒有對應記錄。

OID特點:沒有值

持久態:persistentsession緩存對象,數據庫最終會有記錄。(事務沒有提交)

OID特點:有值

脫管態:detachedsession沒有緩存對象,數據庫有記錄。

OID特點:有值

1.2 轉換

1.2.1 瞬時態/臨時態

l 獲得:一般都只直接創建(new

l 瞬時態 轉換 持久態

一般操作:save方法、saveOrUpdate

l 瞬時態 轉換 脫管態

一般操作:通過setId

方法設置數據

例如:

User user = new User(); //瞬時態

user.setUid(1); //脫管態

1.2.2 持久態

l 獲得:

查詢操作:getloatcreateQuerycreateCriteria 等 獲得都是持久態【】

執行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),hibernatesession中創建多個集合(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 註意1native下,默認OID是否存在,使用默認值。例如:Integer 默認null

通過<id unsaved-value="1"> 修改使用默認值,如果設置1進行insert語句。此內容提供hibernate使用的,錄入到數據庫後,采用自動增長。

2.3.4 delete

總結:

PO對象狀態:瞬時態、持久態、脫管態

Hibernate3 一級緩存