-
瞬時狀態(Transient)
通過new創建對象后,對象並沒有立刻持久化,它並未與數據庫中的數據有任何關聯,此時Java對象的狀態為瞬時狀態。
Session對於瞬時狀態的Java對象是一無所知的,當對象不再被其他對象引用時,它的所有數據也就丟失了,對象將會被Java虛擬機按照垃圾回收機制處理。
-
持久狀態(Persistent)
當對象與Session關聯,被Session管理時,它就處於持久狀態。處於持久狀態的對象擁有數據庫標識(數據庫中的主鍵值)。
那么,對象是什么時候與Session發生關聯的呢?有兩種方法:
第一種,通過Sesison的查詢接口,或者get()方法,或者load()方法從數據庫中加載對象的時候,加載的對象是與數據庫表中的一條記錄關聯的,此時對象與加載它的Session發生關聯;
第二種,瞬時狀態的對象,通過Session的save()方法或SaveOrUpdate()方法時,Java對象也與Session發生關聯。
對於處於持久狀態的對象,Session會持續跟蹤和管理它們,如果對象的內部狀態發生了任何變更,Hibernate會選擇合適的時機(如事務提交時)將變更固化到數據庫中。
-
游離狀態
處於持久狀態的對象,脫離與其關聯的nSession的管理后,對象就處於游離狀態。
處於游離狀態的對象,Session無法保證對象所包含的數據與數據庫中的記錄一直,因為Hibernate已經無法感知對該對象的任何操作。
Session提供了兩個方法(update()、merge()),將處於游離狀態的對象,與一個新的Session發生關聯。
此時,對象的狀態就從游離狀態重新轉換為持久狀態。
2.三種狀態之間的轉換:
使用new關鍵字構件對象,該對象的狀態是瞬時狀態。
1 .瞬時狀態轉為持久狀態
使用Session對象的save()或saveOrUpdate()方法保存對象后,該對象的狀態由瞬時狀態轉換為持久狀態。
使用Session對象的get()或load()方法獲取對象,該對象的狀態是持久狀態。
2. 持久狀態轉為瞬時狀態
執行Session對象的delete()方法后,對象由原來的持久狀態變為瞬時狀態,因為此時該對象沒有與任何的數據庫數據關聯。
3. 持久狀態轉為游離狀態
執行了Session對象的evict()、clear()或close()方法,對象由原來的持久狀態轉為游離狀態。
4 .游離狀態轉為持久狀態
重新獲取Session對象,執行Session對象的update()或saveOrUpdate()方法,對象由游離狀態轉為持久狀態,該對象再次與Session對象相關聯。
5. 游離狀態轉為瞬時狀態
執行Session對象的delete()方法,對象由游離狀態轉為瞬時狀態。
處於瞬時狀態或游離狀態的對象不再被其他對象引用時,會被Java虛擬機按照垃圾回收機制處理。
package com.haidiyixiaoyu.demo; import org.hibernate.Session; import org.junit.Test; import com.haidiyixiaoyu.domain.User; import com.haidiyixiaoyu.utils.HibernateUtils; //對象的三種狀態 public class Demo1 { @Test //演示三種狀態 public void fun1(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ User u = new User(); // 瞬時狀態 u.setName("tom"); // 瞬時狀態 u.setPassword("1234"); // 瞬時狀態 session.save(u); // 持久狀態 //問題: 調用完save方法,數據庫中有沒有對應記錄? // 沒有對應記錄, 但是最終會被同步到數據庫中.仍然是持久狀態. //------------------------------------------------ session.getTransaction().commit(); // 持久狀態 session.close(); // 游離狀態 } @Test //三種狀態的轉換 // 瞬時 => 持久 //瞬時:沒有關聯,沒有id //持久: 有關聯,有id public void fun2(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ User u = new User(); // 瞬時狀態 u.setName("tom"); // 瞬時狀態 u.setPassword("1234"); // 瞬時狀態 session.save(u); // 持久狀態 save方法會使用主鍵生成策略,為User指定id. => //主鍵自增 => 打印 insert語句 //--------------------------// increment=> select max(id) .... //assigned => 需要手動指定主鍵,不指定將會報錯 session.getTransaction().commit(); // 持久狀態 //事務提交時,會把持久化狀態對象同步到數據庫中 session.close(); // 游離狀態 } // 瞬時=> 游離 // 瞬時: 沒有關聯,沒有id // 游離: 沒有關聯,有id(與數據庫中對應的id) @Test public void fun3(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ User u = new User(); // 瞬時狀態 u.setId(1); //游離 //---------------------------------------------------- session.getTransaction().commit(); // 持久狀態 //事務提交時,會把持久化狀態對象同步到數據庫中 session.close(); // 游離狀態 } @Test // 持久=> 瞬時 // 持久: 有關聯,有id // 瞬時: 無關聯,無id public void fun4(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ //通過get方法,得到持久狀態對象 User u= (User) session.get(User.class, 1); // 持久狀態 //---------------------------------------------------- session.getTransaction().commit(); // 持久狀態 //事務提交時,會把持久化狀態對象同步到數據庫中 session.close(); // 游離狀態 u.setId(null);//瞬時狀態 } @Test // 持久=> 瞬時 // 持久: 有關聯,有id // 瞬時: 無關聯,無id public void fun5(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ //通過get方法,得到持久狀態對象 User u= (User) session.get(User.class, 1); // 持久狀態 session.evict(u);//將User對象與session的關聯移除 u.setId(null);//瞬時狀態 session.save(u);//持久狀態 //---------------------------------------------------- session.getTransaction().commit(); // 持久狀態 //事務提交時,會把持久化狀態對象同步到數據庫中 session.close(); // 游離狀態 } // 持久=> 游離 @Test // 持久=> 游離 //持久:有關聯,有id //游離:沒有關聯,有id(與數據庫中對應的id) // 只需要將session的關聯取消 public void fun6(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ //通過get方法,得到持久狀態對象 User u= (User) session.get(User.class, 1); // 持久狀態 session.evict(u);//游離 //---------------------------------------------------- session.getTransaction().commit(); // 游離狀態 session.close(); // 游離狀態 } @Test // 游離=> 瞬時 //游離:沒有關聯,有id(與數據庫中對應的id) //瞬時:無關聯,無id // 移除ID public void fun7(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ //通過get方法,得到持久狀態對象 User u= (User) session.get(User.class, 1); // 持久狀態 session.evict(u);//游離 u.setId(null);// 瞬時 //---------------------------------------------------- session.getTransaction().commit(); // 瞬時狀態 session.close(); // 瞬時狀態 } @Test // 游離=> 持久 //游離:沒有關聯,有id(與數據庫中對應的id) //持久:有關聯,有id // 是否與Session關聯 public void fun8(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ //通過get方法,得到持久狀態對象 User u= (User) session.get(User.class, 1); // 持久狀態 session.evict(u);//游離 session.update(u);//持久 //---------------------------------------------------- session.getTransaction().commit(); // 持久狀態 -> 打印update語句 session.close(); // 瞬時狀態 } //三種狀態有什么用? // 持久狀態,我們使用Hibernate主要是為了持久化我們的數據. // 對於對象的狀態,我們期望我們需要同步到數據庫的數據,都被轉換成持久狀態 //持久化狀態特點: Hibernate會自動將持久化狀態對象的變化同步到數據庫中. @Test public void fun9(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //------------------------------------------------ //通過get方法,得到持久狀態對象 User u= (User) session.get(User.class, 1); // 持久狀態 u.setName("jerry");//持久狀態 // u.setId(3);//與session建立關聯的對象的ID,不允許修改. session.update(u);// 多余=> 因為Hibernate會自動將持久化狀態對象的變化同步到數據庫中. //---------------------------------------------------- session.getTransaction().commit(); // 持久狀態 -> 打印update語句 session.close(); // 瞬時狀態 } }