在 Session 接口的實作中包含一系列的 Java 集合, 這些 Java 集合構成了 Session 緩存. 隻要 Session 執行個體沒有結束生命周期, 且沒有清理緩存,則存放在它緩存中的對象也不會結束生命周期
Session 緩存可減少 Hibernate 應用程式通路資料庫的頻率。
News news = (News) session.get(News.class, 1);
System.out.println(news);
News news2 = (News) session.get(News.class, 1);
System.out.println(news2);
以上語句隻會發送一條sql語句
flush:Session 按照緩存中對象的屬性變化來同步更新資料庫
預設情況下 Session 在以下時間點重新整理緩存:
顯式調用 Session 的 flush() 方法
當應用程式調用 Transaction 的 commit()方法的時, 該方法先 flush ,然後在向資料庫送出事務
當應用程式執行一些查詢(HQL, Criteria)操作時,如果緩存中持久化對象的屬性已經發生了變化,會先 flush 緩存,以保證查詢結果能夠反映持久化對象的最新狀态
flush 緩存的例外情況: 如果對象使用 native 生成器生成 OID, 那麼當調用 Session 的 save() 方法儲存對象時, 會立即執行向資料庫插入該實體的 insert 語句.
commit() 和 flush() 方法的差別:flush 執行一系列 sql 語句,但不送出事務;commit 方法先調用flush() 方法,然後送出事務. 意味着送出事務意味着對資料庫操作永久儲存下來。
/**
* flush: 使資料表中的記錄和 Session 緩存中的對象的狀态保持一緻. 為了保持一緻, 則可能會發送對應的 SQL 語句.
* 1. 在 Transaction 的 commit() 方法中: 先調用 session 的 flush 方法, 再送出事務
* 2. flush() 方法會可能會發送 SQL 語句, 但不會送出事務.
* 3. 注意: 在未送出事務或顯式的調用 session.flush() 方法之前, 也有可能會進行 flush() 操作.
* 1). 執行 HQL 或 QBC 查詢, 會先進行 flush() 操作, 以得到資料表的最新的記錄
* 2). 若記錄的 ID 是由底層資料庫使用自增的方式生成的, 則在調用 save() 方法時, 就會立即發送 INSERT 語句.
* 因為 save 方法後, 必須保證對象的 ID 是存在的!
*/
@Test
public void testSessionFlush2(){
News news = new News("Java", "SUN", new Date());
session.save(news);
}
@Test
public void testSessionFlush(){
News news = (News) session.get(News.class, 1);
news.setAuthor("Oracle");
// session.flush();
// System.out.println("flush");
//執行 HQL 或 QBC 查詢, 會先進行 flush() 操作, 以得到資料表的最新的記錄
News news2 = (News) session.createCriteria(News.class).uniqueResult();
System.out.println(news2);
}
/**
* refresh(): 會強制發送 SELECT 語句, 以使 Session 緩存中對象的狀态和資料表中對應的記錄保持一緻!
*/
@Test
public void testRefresh(){
News news = (News) session.get(News.class, 1);
System.out.println(news);
session.refresh(news);
System.out.println(news);
}
以上的
refresh()
要把資料庫的隔離級别設定為以下才有用:
<!-- 設定 Hibernate 的事務隔離級别 -->
<property name="connection.isolation">2</property>
/**
* clear(): 清理緩存
*/
@Test
public void testClear(){
News news1 = (News) session.get(News.class, 1);
session.clear();
News news2 = (News) session.get(News.class, 1);
}
以上代碼會發送兩條sql語句,因為clear()已經把緩存清理掉了