# hibernate 2/20 觀念 ###### tags: `hibernate` #### @ 永續類別 ![](https://i.imgur.com/GHBAmni.png) #### 可寫可不寫(不寫要自行修改) ![](https://i.imgur.com/HdKIuwZ.png) #### 第五章介紹 ![](https://i.imgur.com/zmtknAm.png) #### 永續類別 ![](https://i.imgur.com/DMLL1qV.png) ![](https://i.imgur.com/ofLLUSZ.png) ### 32 編寫Hibernate程式的通則 ![](https://i.imgur.com/JFDwq54.png) 建工廠 ![](https://i.imgur.com/ZvmrEPp.png) 對 [HibernateUtils] F3 OR ctrl+左鍵 可進入以下畫面 ![](https://i.imgur.com/7mnzmPK.png) 類別載入過不會再載入 實作類別介面做工廠 ![](https://i.imgur.com/iKVpttp.png) 呼叫工廠(兩種方法都合法) ![](https://i.imgur.com/S8wVHeG.png) 開啟交易 ![](https://i.imgur.com/jYnB7bl.png) 這個類別只做開啟交易 ![](https://i.imgur.com/K6PZxuA.png) 再度丟出例外 ![](https://i.imgur.com/k84Le3f.png) 多個表格異動 ![](https://i.imgur.com/ofb7oSF.png) 其中一個DAO出問題可能是企業邏輯異常(企業組絕定的邏輯) 還原異動前的狀態 ![](https://i.imgur.com/84nPKC8.png) * **Hibernaet** * 交易邊界 哪裡開始哪裡結束(交易) * 結束要回滾(還原到正常狀態) * 即便做查詢也要開啟交易Hibernate的規定 多個DAO都用同一個執行緒 Session物件 DAO會拿到一樣的的Session物件 關閉 Session openSession(自行關閉) getCurrentSession ![](https://i.imgur.com/pZPrJ5Z.png) 有了 @Transactional 註解那邊通通不用寫 (需要Spring) ![](https://i.imgur.com/mLLxyGU.png) ### 47~51 程式實作 ![](https://i.imgur.com/XKhmy4X.png) * **Hibernate分為** * 一對多 多對一 看主角是誰? * 主角不同會有差異 ![](https://i.imgur.com/vLOFEBV.png) Spring都使用介面 (不要寫類別名稱) 實作介面類別 ![](https://i.imgur.com/ZhJvDJ5.png) 修改 ![](https://i.imgur.com/vZ991FS.png) 使用組態檔 ![](https://i.imgur.com/XLhDgUn.png) Impl結尾都是實作介面類別的名字 建立工廠需要組態資訊 * **sql** * 外鍵 建在多方建一個就可 * 主鍵 建在一方 連動 ![](https://i.imgur.com/RmUiZd3.png) all的時候 ![](https://i.imgur.com/d3Xy57N.png) ![](https://i.imgur.com/mjQFlEL.png) 當儲存 關聯物件沒有儲存 要順便存起來 如果有其他的永續物件沒有儲存會出現這個 ![](https://i.imgur.com/juot4t5.png) ### 54 永續儲存的類別(永續類別)Persistence Class ![](https://i.imgur.com/T05metH.png) final類別不可以有子類別 需要告訴組態檔 ![](https://i.imgur.com/7btni4n.png) ![](https://i.imgur.com/udpDAO8.png) ### 55 POJO類別 ![](https://i.imgur.com/uZlVgMU.png) 不要實作任何界面或者繼承父類別 Domain類似業務相關 OID可挑流水號做 ### 56 POJO類別範例 越單純越好 ![](https://i.imgur.com/dVCYwfT.png) ### 58 永續物件的生命週期(重要) 1. Transien 短暫 暫時 2. Persistent 永久保留 永續 3. Detached 分離物件 沒有跟儲存環境連接的 4. Removed 刪除移除 ![](https://i.imgur.com/gwsKN3I.png) ### 59 物件在Hibernate內生命週期的變化 ![](https://i.imgur.com/JTMDnTg.png) ### 60 Transient(臨時)狀態 ![](https://i.imgur.com/dz8HxVu.png) ### 口試常問 61 Persistent(永續)狀態 ![](https://i.imgur.com/MIlVTYt.png) 如果一個永續物件的屬性改變 它有可能會更新也可能不更新 ### 口試 62 Detached(分離)狀態 ![](https://i.imgur.com/xsYCB1a.png) evict移出一次 clear全部逐出 * **Persistent(永續)狀態** * 永續物件 有oid 有主見紀錄 放session緩存 * **Detached(分離)狀態** * 分離物件 分離也有主見對應值 不會緩存 不受到hibernate監控 ### 63 Removed(移除)狀態 移除就是刪除對應的紀錄 ![](https://i.imgur.com/RbIoLKe.png) ### 64 JUnit 單元測試工具 ![](https://i.imgur.com/6d7Xzn4.png) #### 實作 ![](https://i.imgur.com/J4eixUd.png) ![](https://i.imgur.com/Ah513eC.png) ![](https://i.imgur.com/YqwQdej.png) ![](https://i.imgur.com/tqtpikZ.png) ```click= package jut2; import static org.junit.Assert.*; import org.junit.After; import org.junit.Before; import org.junit.Test; public class MyJUint02 { @Before public void setUp() throws Exception { System.out.println("Before"); } @After public void tearDown() throws Exception { System.out.println("After"); } @Test public void test() { System.out.println("Test"); } @Test public void test1() { System.out.println("Test1"); } } ``` ![](https://i.imgur.com/veneY5i.png) ### 找專案 ![](https://i.imgur.com/VG7oMqN.png) 詳細尋找 找目前專案 ![](https://i.imgur.com/uUtit8P.png) ### 註解顏色 ![](https://i.imgur.com/Kw0OHxA.png) ### debug ![](https://i.imgur.com/XcmQg5v.jpg) ![](https://i.imgur.com/sFyJpV1.png) ![](https://i.imgur.com/lxCBEFF.png) 直接跳到下一個中斷點 ![](https://i.imgur.com/UszrXIC.png) ### 72-73 Session介面的get()與load()方法 ![](https://i.imgur.com/MLc3vY1.png) Lazy Loading延遲載入 * **Member.class** * 儲存Member類別的內容的物件 * 一個class型別的物件 * ![](https://i.imgur.com/LsgSDGv.png) ![](https://i.imgur.com/9sIviPK.png) 一對多 多對一 的多方會用到Lazy Loading ### 74 Session介面的get() ![](https://i.imgur.com/QpN1cTi.png) ### 實作畫面 ![](https://i.imgur.com/VIKuh8F.png) 所有的中斷點 ![](https://i.imgur.com/yvyprQ3.png) ![](https://i.imgur.com/KdXsBTJ.png) ```click= org.hibernate.LazyInitializationException: could not initialize proxy [ch03._00.model.BookBean#3] - no Session at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:170) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:310) at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45) at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) at ch03._00.model.BookBean$HibernateProxy$5tKaOrzS.getAuthor(Unknown Source) at ch03._00.MethodsOfSession.loadDemo01(MethodsOfSession.java:153) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210) ``` ![](https://i.imgur.com/9uUnu9E.png) ![](https://i.imgur.com/tLDnyqa.png) ![](https://i.imgur.com/w2hrKrI.png) mydebug ![](https://i.imgur.com/NMooDoP.png) ![](https://i.imgur.com/BWPVLg7.png) ## merge merge傳回值是永續物件 但參數不是 ### 實作dao ```click= @SuppressWarnings("unchecked") @Override public List<MemberBean> getAllMembers() { String hql = "FROM MemberBean";//FROM 類別名稱 Session session = factory.getCurrentSession(); List<MemberBean> list = session.createQuery(hql).getResultList(); return list; } @Override public MemberBean getMember(int pk) { Session session = factory.getCurrentSession(); MemberBean mb = session.get(MemberBean.class, pk); return mb; } @Override public int deleteMember(int pk) { int count = 0; Session session = factory.getCurrentSession(); MemberBean mb = new MemberBean(); mb.setPk(pk); session.delete(mb); count++; return count; } @Override public int updateMember(MemberBean mb) { int count = 0; Session session = factory.getCurrentSession(); session.merge(mb); count++; return count; } ``` ### Service ```click= @Override public List<MemberBean> getAllMembers() { List<MemberBean> list = null; Session session = factory.getCurrentSession(); Transaction tx = null; try { tx = session.beginTransaction(); list = dao.getAllMembers(); tx.commit(); } catch (Exception e) { if(tx != null) { tx.rollback(); } throw new RuntimeException(); } return list; } @Override public MemberBean getMember(int pk) { MemberBean mb = null; Session session = factory.getCurrentSession(); Transaction tx = null; try { tx = session.beginTransaction(); mb = dao.getMember(pk); tx.commit(); } catch (Exception e) { if(tx != null) { tx.rollback(); } e.printStackTrace(); throw new RuntimeException(); } return mb; } @Override public int deleteMember(int ipk) { int n = 0; Session session = factory.getCurrentSession(); Transaction tx = null; try { tx = session.beginTransaction(); n = dao.deleteMember(ipk); tx.commit(); } catch (Exception e) { if(tx != null) { tx.rollback(); } e.printStackTrace(); throw new RuntimeException(); } return n; } @Override public int updateMember(MemberBean mb) { int n = 0; Session session = factory.getCurrentSession(); Transaction tx = null; try { tx = session.beginTransaction(); n = dao.updateMember(mb); tx.commit(); } catch (Exception e) { if(tx != null) { tx.rollback(); } e.printStackTrace(); throw new RuntimeException(); } return n; } ``` ### 102 延遲加載Lazy Initialization ![](https://i.imgur.com/VY9T4NU.png) ### 103 在MVC架構下http請求地處理流程 ![](https://i.imgur.com/wDrZOQK.jpg) ### 104-107 解決Lazy Loading的做法 ![](https://i.imgur.com/0pSCBg2.png) EAGER急切 ![](https://i.imgur.com/KNBD0NF.png) ![](https://i.imgur.com/ilQygW1.png) 交易都沒有commit session都是開啟狀態 控制器做完才回到Filter才去關閉commit ![](https://i.imgur.com/urZ7dGr.png) ![](https://i.imgur.com/zOhDEDg.png) ![Uploading file..._ov2sqz688]() > [name=黑咖啡好喝]