標籤:對象狀態 ddc 沒有 二級緩衝 儲存 屬性 row list 語句
回顧Hibernate第二天:
1. 一對多與多對一
2. 多對多
3. inverse/cascade
4. 關聯關係的維護
一對多:
<set name="映射的集合屬性" table="(可選)集合屬性對應的外鍵表">
<key column="外鍵表的,外鍵欄位" />
<one-to-many class="集合元素的類型" />
</set>
多對一:
<many-to-one name="對象屬性" class="物件類型" column="外鍵欄位欄位" />
多對多
<set name="" table="">
<key column="" />
<many-to-many column="" class="">
</set>
目標:
第1部分: 對象的狀態:
第2部分:緩衝
1) 一級緩衝
2) 相關知識
----懶載入---
第3部分:映射
一對一映射
組件映射
繼承映射
一、對象的狀態
舉例: User user = new User();
Hibernate中對象的狀態: 臨時/瞬時狀態、持久化狀態、游離狀態。
1. 臨時狀態
特點:
直接new出來的對象;
不處於session的管理;
資料庫中沒有對象的記錄;
1. 持久化狀態
當調用session的save/saveOrUpdate/get/load/list等方法的時候,對象就是持久化狀態。
處於持久化狀態的對象,當對對象屬性變更的時候,會反映到資料庫中!
特點:
處於session的管理;
資料庫中有對應的記錄;
3. 游離狀態
特點:
不處於session的管理;
資料庫中有對應的記錄
Session關閉後,對象的狀態;
對象狀態的轉換
public class User { private int userId; private String userName; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @Override public String toString() { return "User [userId=" + userId + ", userName=" + userName + "]"; } }
<hibernate-mapping package="cn.itcast.a_status"> <class name="User" table="t_user"> <id name="userId" column="id"> <generator class="native"></generator> </id> <property name="userName"></property> </class> </hibernate-mapping>
public class App1_status { private static SessionFactory sf; static { sf = new Configuration() .configure() .addClass(User.class) // 測試時候使用 .buildSessionFactory(); } //1. 對象狀態的轉換 @Test public void testSaveSet() throws Exception { Session session = sf.openSession(); session.beginTransaction(); // 建立對象 【臨時狀態】// User user = new User();// user.setUserName("Jack22222"); // 儲存 【持久化狀態】// session.save(user); // user.setUserName("Jack333333"); // 會反映到資料庫 // 查詢 User user = (User) session.get(User.class, 5); user.setUserName("Tomcat");// hibernate會自動與資料庫匹配(一級緩衝),如果一樣就更新資料庫 session.getTransaction().commit(); session.close(); user.setUserName("Jack444444444"); // 列印 【游離狀態】 System.out.println(user.getUserId()); System.out.println(user.getUserName()); } @Test public void bak() throws Exception { Session session = sf.openSession(); session.beginTransaction(); session.getTransaction().commit(); session.close(); }}
二、一級緩衝
為什麼要用緩衝?
目的:減少對資料庫的訪問次數!從而提升hibernate的執行效率!
Hibernate中緩衝分類:
一級緩衝
二級緩衝
ü 概念
1)Hibenate中一級緩衝,也叫做session的緩衝,它可以在session範圍內減少資料庫的訪問次數! 只在session範圍有效! Session關閉,一級緩衝失效!
2)當調用session的save/saveOrUpdate/get/load/list/iterator方法的時候,都會把對象放入session的緩衝中。
3)Session的緩衝由hibernate維護, 使用者不能操作緩衝內容; 如果想操作緩衝內容,必須通過hibernate提供的evit/clear方法操作。
特點:
只在(當前)session範圍有效,作用時間短,效果不是特別明顯!
在短時間內多次操作資料庫,效果比較明顯!
ü 緩衝相關幾個方法的作用
session.flush(); 讓一級緩衝與資料庫同步
session.evict(arg0); 清空一級緩衝中指定的對象
session.clear(); 清空一級緩衝中緩衝的所有對象
在什麼情況用上面方法?
大量操作使用使用:
Session.flush(); // 先與資料庫同步
Session.clear(); // 再清空一級緩衝內容
ü 面試題1: 不同的session是否會共用快取資料? 不會。
User1 u1 = Session1.get(User.class,1); 把u1對象放入session1的緩衝
Session2.update(u1); 把u1放入session2的緩衝
U1.setName(‘new Name’);
如果產生2條update sql, 說明不同的session使用不同的緩衝區,不能共用。
ü 面試題2: list與iterator查詢的區別?
list()
一次把所有的記錄都查詢出來,
會放入緩衝,但不會從緩衝中擷取資料
Iterator
N+1查詢; N表示所有的記錄總數
即會先發送一條語句查詢所有記錄的主鍵(1),
再根據每一個主鍵再去資料庫查詢(N)!
會放入緩衝,也會從緩衝中取資料!
public class App2_cache { private static SessionFactory sf; static { sf = new Configuration() .configure() .addClass(User.class) // 測試時候使用 .buildSessionFactory(); } @Test public void testCache() throws Exception { Session session = sf.openSession(); session.beginTransaction(); User user = null; // 查詢 user = (User) session.get(User.class, 5);// 先檢查緩衝中是否有資料,如果有不查詢資料庫,直接從緩衝中擷取 user = (User) session.get(User.class, 5);// 這一句就不再向資料庫發送查詢命令了,減少了與資料庫的互動。 session.getTransaction().commit(); session.close(); } @Test public void flush() throws Exception { Session session = sf.openSession(); session.beginTransaction(); User user = null; user = (User) session.get(User.class, 5); user.setUserName("Jack"); // 快取資料與資料庫同步 session.flush(); user.setUserName("Jack_new"); session.getTransaction().commit(); // session.flush(); session.close(); } @Test public void clear() throws Exception { Session session = sf.openSession(); session.beginTransaction(); User user = null; // 查詢 user = (User) session.get(User.class, 5); // 清空緩衝內容 // session.clear(); // 清空所有 session.evict(user);// 清除指定 user = (User) session.get(User.class, 5); session.getTransaction().commit(); // session.flush(); session.close(); } @Test public void sessionTest() throws Exception { Session session1 = sf.openSession(); session1.beginTransaction(); Session session2 = sf.openSession(); session2.beginTransaction(); // user放入session1的緩衝區 User user = (User) session1.get(User.class, 1); // user放入session2的緩衝區 session2.update(user); // 修改對象 user.setUserName("New Name"); // 2條update session1.getTransaction().commit(); // session1.flush(); session1.close(); session2.getTransaction().commit(); // session2.flush(); session2.close(); }}
Hibernate架構--對象的狀態,緩衝, 映射