標籤:ext 理解 unit div bsp 二次 contex rup update
public class StudentTest { Session session=null; Transaction transaction=null; //在執行測試方法之前 先執行before @Before public void before(){ /** * 01.讀取核心的設定檔 在src的根目錄下面! 底層規定位置! * 在執行個體化Configuration對象的時候通過configure() * 去src根目錄下面,尋找hibernate.cfg.xml檔案 */ Configuration configuration=new Configuration().configure(); //02.建立sessionFactory SessionFactory sessionFactory = configuration.buildSessionFactory(); //03.開啟session session = sessionFactory.openSession(); //04.開啟事務 transaction= session.beginTransaction(); } //在執行測試方法之後 @After public void after(){ //07.提交事務 sql語句 整體的執行! transaction.commit(); //08.關閉session session.close(); //sessionFactory.close(); 驗證hbm2ddl中的create-drop } /** * hibernate對象的三種狀態! * 01.瞬時狀態(臨時狀態/自由狀態) * 我們通過new關鍵字 建立出的一個實體物件!和hibernate沒有半毛錢關係! * * 02.持久狀態 * 對象正在被session管理,資料庫中有對象 對應的資料! * 如果對象是持久狀態! 那麼對它的修改操作 不需要再使用其他的方法(update) * 在commit的時候,會執行flush(), * flush()的時候會進行緩衝清理! * 緩衝清理的時候會進行髒檢查! * 如果對象的屬性和之前的對象屬性不一致! * 那麼當前的對象就是髒對象! * 就會把髒對象同步到資料庫! * * 03.游離狀態(脫管狀態) * 曾經被session管理過!和瞬時狀態的區別就是 是否存在OID(主鍵標識符)! * */ @Test public void testSave1(){ //建立一個對象 Student stu=new Student(100, 50, "老白"); //瞬時狀態 session.save(stu); //持久化狀態 stu.setName("老白乾"); /** 改變了對象的屬性 這時候的stu就是髒對象 不需要執行update() commit的時候會產生兩條sql語句! 01.insert 02.update */ } @Test public void testSave02(){ //建立一個對象 Student stu=new Student(666, 50, "老白"); //瞬時狀態 stu.setName("老白乾"); //瞬時狀態 session.save(stu); //持久化狀態 從這裡開始 才被 session管理! } @Test public void testSave03(){ //建立一個對象 Student stu=new Student(555, 50, "老白"); //瞬時狀態 stu.setName("老白乾"); //瞬時狀態 session.save(stu); //持久化狀態 從這裡開始 才被 session管理! stu.setName("老白乾1"); stu.setName("老白乾2"); stu.setName("老白乾3"); /** * 還是兩條sql語句 *commit的時候會產生兩條sql語句! 01.insert 02.update */ } /** * 測試方法的前提環境三種情況 * 01.stu對象在資料庫中沒有對應的資料 * 02.stu對象在資料庫中有對應的資料,但是我們沒有修改屬性 * 03.stu對象在資料庫中有對應的資料,我們修改了屬性 * 產生的結果都是一致的! * 根據id 產生update語句 */ @Test public void testUpdate(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.update(stu); } /** * 測試方法的前提環境 * stu對象在資料庫中沒有對應的資料 * 產生的結果: * 01.根據id 產生 select * 02.探索資料庫中沒有對應的資料 產生 insert */ @Test public void testSaveOrUpdate(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.saveOrUpdate(stu); } /** * 測試方法的前提環境 * 01.stu對象在資料庫有對應的資料 * 02.沒有改變stu對象的屬性值 * 產生的結果: * 根據id 產生 select語句 */ @Test public void testSaveOrUpdate2(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.saveOrUpdate(stu); } /** * 測試方法的前提環境 * 01.stu對象在資料庫有對應的資料 * 02.改變了stu對象的屬性值 * 產生的結果: * 01.根據id 產生 select * 02.因為修改了對象的屬性 所以 執行update */ @Test public void testSaveOrUpdate3(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 stu.setName("老白乾"); session.saveOrUpdate(stu); } }
package cn.bdqn.test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.junit.After;import org.junit.Before;import org.junit.Test;import cn.bdqn.bean.Student;public class StudentTest { Session session=null; Transaction transaction=null; //在執行測試方法之前 先執行before @Before public void before(){ /** * 01.讀取核心的設定檔 在src的根目錄下面! 底層規定位置! * 在執行個體化Configuration對象的時候通過configure() * 去src根目錄下面,尋找hibernate.cfg.xml檔案 */ Configuration configuration=new Configuration().configure(); //02.建立sessionFactory SessionFactory sessionFactory = configuration.buildSessionFactory(); //03.開啟session session = sessionFactory.openSession(); //04.開啟事務 transaction= session.beginTransaction(); } //在執行測試方法之後 @After public void after(){ //07.提交事務 sql語句 整體的執行! transaction.commit(); //08.關閉session session.close(); //sessionFactory.close(); 驗證hbm2ddl中的create-drop } /** * hibernate對象的三種狀態! * 01.瞬時狀態(臨時狀態/自由狀態) * 我們通過new關鍵字 建立出的一個實體物件!和hibernate沒有半毛錢關係! * * 02.持久狀態 * 對象正在被session管理,資料庫中有對象 對應的資料! * 如果對象是持久狀態! 那麼對它的修改操作 不需要再使用其他的方法(update) * 在commit的時候,會執行flush(), * flush()的時候會進行緩衝清理! * 緩衝清理的時候會進行髒檢查! * 如果對象的屬性和之前的對象屬性不一致! * 那麼當前的對象就是髒對象! * 就會把髒對象同步到資料庫! * * 03.游離狀態(脫管狀態) * 曾經被session管理過!和瞬時狀態的區別就是 是否存在OID(主鍵標識符)! * */ @Test public void testSave1(){ //建立一個對象 Student stu=new Student(100, 50, "老白"); //瞬時狀態 session.save(stu); //持久化狀態 stu.setName("老白乾"); /** 改變了對象的屬性 這時候的stu就是髒對象 不需要執行update() commit的時候會產生兩條sql語句! 01.insert 02.update */ } @Test public void testSave02(){ //建立一個對象 Student stu=new Student(666, 50, "老白"); //瞬時狀態 stu.setName("老白乾"); //瞬時狀態 session.save(stu); //持久化狀態 從這裡開始 才被 session管理! } @Test public void testSave03(){ //建立一個對象 Student stu=new Student(555, 50, "老白"); //瞬時狀態 stu.setName("老白乾"); //瞬時狀態 session.save(stu); //持久化狀態 從這裡開始 才被 session管理! stu.setName("老白乾1"); stu.setName("老白乾2"); stu.setName("老白乾3"); /** * 還是兩條sql語句 *commit的時候會產生兩條sql語句! 01.insert 02.update */ } /** * 測試方法的前提環境三種情況 * 01.stu對象在資料庫中沒有對應的資料 * 02.stu對象在資料庫中有對應的資料,但是我們沒有修改屬性 * 03.stu對象在資料庫中有對應的資料,我們修改了屬性 * 產生的結果都是一致的! * 根據id 產生update語句 ! 只能是從游離變持久! */ @Test public void testUpdate(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.update(stu); } /** * 測試方法的前提環境 * stu對象在資料庫中沒有對應的資料 * 產生的結果: * 01.根據id 產生 select * 02.探索資料庫中沒有對應的資料 產生 insert */ @Test public void testSaveOrUpdate(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.saveOrUpdate(stu); } /** * 測試方法的前提環境 * 01.stu對象在資料庫有對應的資料 * 02.沒有改變stu對象的屬性值 * 產生的結果: * 根據id 產生 select語句 */ @Test public void testSaveOrUpdate2(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.saveOrUpdate(stu); } /** * 測試方法的前提環境 * 01.stu對象在資料庫有對應的資料 * 02.改變了stu對象的屬性值 * 產生的結果: * 01.根據id 產生 select * 02.因為修改了對象的屬性 所以 執行update */ @Test public void testSaveOrUpdate3(){ //建立一個對象 Student stu=new Student(1, 50, "老白"); //瞬時狀態 stu.setName("老白乾"); session.saveOrUpdate(stu); } /** * 測試方法的前提環境 * stu對象在資料庫沒有對應的資料 * 產生的結果: * 兩條sql * 01.select 先去資料庫中查詢有沒有id對應的資料 * 02.執行 insert */ @Test public void testMerge01(){ Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.merge(stu); } /** * 測試方法的前提環境 * stu對象在資料庫有對應的資料 ,我們沒有修改對象的屬性 * 產生的結果: * 只有select語句 */ @Test public void testMerge02(){ Student stu=new Student(1, 50, "老白"); //瞬時狀態 session.merge(stu); } /** * 測試方法的前提環境 * stu對象在資料庫有對應的資料 ,我們修改了對象的屬性 * 產生的結果: * 01.select * 02.update */ @Test public void testMerge03(){ Student stu=new Student(1, 50, "老白"); //瞬時狀態 stu.setName("老白乾"); session.merge(stu); } /** * 測試方法的前提環境 * stu對象在資料庫有對應的資料 ,我們修改了對象的屬性 * 產生的結果: * 報錯 */ @Test public void testMerge04(){ Student stu=new Student(1, 50, "老白乾"); //瞬時狀態 session.merge(stu); //不會改變對象的狀態 stu.setName("老白11111"); //瞬時狀態 session.update(stu); //報錯 } /** * save(): 把瞬時狀態轉換成 持久狀態 * update():把游離狀態轉換成 持久狀態 * saveOrUpdate(): * 會根據持久化對象的主鍵標識符來判斷是執行save()還是update() * 如果沒有oid,證明是瞬時狀態,就執行save(); * 如果有oid,證明是游離狀態,就執行update(); * merge: 雖然和saveOrUpdate()產生的sql結果一致! * 但是: * 01.merge不會改變對象的狀態! * 02.當對象處於瞬時狀態的時候,會將對象賦值一份到session的緩衝中,執行save() ,產生insert語句! * 我們認為 產生了 insert語句,stu就變成了持久化對象!其實不是! * 只不過是session緩衝中的對象發生了變化! */ }
/** * 第一步: *01.讀取設定檔 hibernate.cfg.xml *02.建立會話工廠---》確保工廠是單例模式 *03.提供對外訪問的介面 *第二步: * 在核心設定檔中 管理我們的currentSession */public class HibernateSessionUtil { private static Configuration configuration; private static SessionFactory sessionFactory; private HibernateSessionUtil(){}//私人化構造 //在類被載入的時候 執行靜態代碼塊 static{ configuration=new Configuration().configure(); sessionFactory=configuration.buildSessionFactory();//擷取會話工廠 } //擷取session的方法 public static Session getCurrentSession(){ return sessionFactory.getCurrentSession(); } }
hibernate.cfg.xml檔案中新增
<!-- 配置我們的currentSession --> <property name="current_session_context_class">thread</property>
測試代碼
public class SessionTest { public static void main(String[] args) { /**Configuration configuration=new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); //第一次 System.out.println(session.hashCode()); session = sessionFactory.openSession(); //第二次 System.out.println(session.hashCode()); hashCode不一致 */ //通過我們自己建立的回話工廠來建立currentSession Session session = HibernateSessionUtil.getCurrentSession(); //第一次 System.out.println(session.hashCode()); session = HibernateSessionUtil.getCurrentSession(); //第二次 System.out.println(session.hashCode()); //hashCode一致 }}
/** * flush和commit的區別! * * 相同點: * 兩者都會同步到資料庫! * * 不同點: * commit:永久儲存! commit--->flush()-->緩衝清理--->髒檢查 * * flush: 不會永久儲存! * 01.是執行緩衝清理工作! * 02.會把緩衝中的對象同步到資料庫中!但是不會儲存! * 03.確保緩衝中的資料 和資料庫中的資料一致! * * 緩衝清理機制: * 在我們執行flush()的時候,會清理session中的資料! * 在清理緩衝的的時候,會執行髒檢查! * 髒檢查: * 在對象被session管理的時候! * 01.session會在緩衝中建立出 對象的快照儲存現在對象的一個狀態以及屬性! (a對象) * 02.在清理緩衝的時候會把現在對象的屬性和(a對象)進行比對! * 03.發現現在的對象和(a對象不一致!那麼現在的對象就稱之為 髒對象! * 04.flush()會把這個髒對象 同步到 資料庫! 但是不會儲存!只是暫時的! * 05.之後commit的時候 才能永久儲存資料! * */ @Test public void test01(){ //通過工具類擷取session Session session = HibernateSessionUtil.getCurrentSession(); //擷取事務 Transaction transaction = session.beginTransaction(); Student stu=(Student) session.get(Student.class, 1);//持久化對象 stu.setName("能改變嗎?"); /** * 清理緩衝 * 按照我們的理解,沒有commit是不可能提交事務的!言外之意!資料庫中的資料不會改變! */ System.out.println("*****************"); session.flush(); stu.setName("能改變嗎2?"); System.out.println("*****************"); Student stu2=(Student) session.get(Student.class, 1); System.out.println(stu2.getName()); //已經改變了! } @Test public void test02(){ //通過工具類擷取session Session session = HibernateSessionUtil.getCurrentSession(); //擷取事務 Transaction transaction = session.beginTransaction(); Student stu=(Student) session.get(Student.class, 1);//持久化對象 stu.setName("能改變嗎?"); System.out.println("*****************"); session.flush(); //執行 sql stu.setName("能改變嗎2?"); //之後又改變了 值 System.out.println("*****************"); /** * 緩衝中的OID是一致的! * get() * 01.查詢session緩衝 * 02.發現緩衝中有資料 直接使用 * 03.所以說 stu2的name必須是 “ 能改變嗎2?” */ Student stu2=(Student) session.get(Student.class, 1); System.out.println(stu2.getName()); //改變了第2次!! ! }
hibernate04--三種狀態之間的轉換