Hibernate Session概述
Session接口是Hibernate向應用程序提供的操縱數(shù)據(jù)庫的最主要的接口,它提供了基本的保存、更新、刪除和加載java對象的方法。
Session具有一個緩存,位于緩存中的對象稱為持久化對象,它和數(shù)據(jù)庫中的相關記錄對應。Session能夠在某些時間點,按照緩存中對象的變化來執(zhí)行相關的SQL語句,來同步更新數(shù)據(jù)庫,這一過程被稱為刷新緩存(flush)。
站在持久化的角度,Hibernate把對象分為4種狀態(tài):持久化狀態(tài)、臨時狀態(tài)、游離狀態(tài)、刪除狀態(tài)。Session的特定方法能使對象從一個狀態(tài)轉換到另一個狀態(tài)。
Session緩存
在Session接口的實現(xiàn)中包含一系列的Java集合,這些Java集合構成了Session緩存。只要Session實例沒有結束生命周期,且沒有清理緩存,則存放在它緩存中的對象也不會結束生命周期。
Session緩存可減少Hibernate應用程序訪問數(shù)據(jù)庫的頻率。
操作Session緩存:
flush():Session按照緩存中對象的屬性來同步更新數(shù)據(jù)庫
默認情況下Session會在以下時間點刷新緩存: 顯式調用Session的flush()方法 當應用程序調用Transaction的commit()方法時,該方法先刷新緩存(flush),然后向數(shù)據(jù)庫提交事務 當應用程序執(zhí)行一下兒查詢(HQL,Criteria)操作時,如果緩存中持久化對象的屬性已經發(fā)生了變化,會先flush()緩存,以保證查詢結果能夠反映持久化對象的最新狀態(tài)
flush緩存的例外情況:如果對象使用native生成器生成OID,那么當調用Session的save()方法保存對象時,會立即執(zhí)行向數(shù)據(jù)庫插入改實體的insert語句。commit()和flush()方法的區(qū)別:flush執(zhí)行一系列的sql語句,但不提交事務;commit方法先調用flush方法,然后提交事務,意味著提交事務,意味著對數(shù)據(jù)庫操作永久保存下來。 refresh():會強制發(fā)送SELECT 語句,以使Session緩存中對象的狀態(tài)和數(shù)據(jù)表中對應的記錄保持一致! clear():清理緩存
測試類:
1 package com.yl.hibernate.entities; 2 3 import static org.junit.Assert.*; 4 5 import java.util.Date; 6 7 import org.hibernate.Session; 8 import org.hibernate.SessionFactory; 9 import org.hibernate.Transaction; 10 import org.hibernate.cfg.Configuration; 11 import org.hibernate.service.ServiceRegistry; 12 import org.hibernate.service.ServiceRegistryBuilder; 13 import org.junit.After; 14 import org.junit.Before; 15 import org.junit.Test; 16 17 public class HibernateTest { 18 19 PRivate SessionFactory sessionFactory; 20 private Session session; 21 private Transaction transaction; 22 23 @Before 24 public void init() { 25 Configuration configuration = new Configuration().configure(); 26 ServiceRegistry serviceRegistry = 27 new ServiceRegistryBuilder().applySettings(configuration.getProperties()) 28 .buildServiceRegistry(); 29 30 sessionFactory = configuration.buildSessionFactory(serviceRegistry); 31 32 session = sessionFactory.openSession(); 33 34 transaction = session.beginTransaction(); 35 } 36 @After 37 public void destory() { 38 transaction.commit(); 39 40 session.close(); 41 42 sessionFactory.close(); 43 } 44 45 @Test 46 public void testSessionCache() { 47 News news = (News)session.get(News.class, 21); 48 System.out.println(news); 49 session.flush(); 50 News news2 = (News)session.get(News.class, 21); 51 System.out.println(news2); 52 53 System.out.println(news == news2);//true 54 } 55 56 /** 57 * flush:使數(shù)據(jù)庫表中的記錄和Session緩存中的對象的狀態(tài)保持一致。為了保持一致,則可能會發(fā)送對應的SQL語句。 58 * 1.在Transaction的commit()方法中:先調用session的flush方法,再提交事務 59 * 2.flush()方法可能會發(fā)送SQL語句,但不會提交事務 60 * 3.注意:在為提交事務或顯示調用session.flush()方法 之前,也有可能會flush()操作。 61 * 1).執(zhí)行HQL或QBC查詢,會先進行flush操作,以得到數(shù)據(jù)表的最新紀錄 62 * 2).若記錄的ID是由底層數(shù)據(jù)庫使用自增的方式生成的,則在調用save方法時,就會立即發(fā)送INSERT語句 63 * 因為save方法后,必須保證對象的ID是存在的! 64 */ 65 @Test 66 public void testFlush2() { 67 News news = new News("Hibernate", "Oracle", new Date()); 68 session.save(news); 69 } 70 71 @Test 72 public void testFlush() { 73 News news = (News)session.get(News.class, 21); 74 news.setAuthor("Bruce Eckel"); 75 76 News news2 = (News)session.createCriteria(News.class).uniqueResult(); 77 System.out.println(news2); 78 } 79 80 /** 81 * refresh():會強制發(fā)送SELECT 語句,以使Session緩存中對象的狀態(tài)和數(shù)據(jù)表中對應的記錄保持一致! 82 */ 83 @Test 84 public void testRefresh() { 85 News news = (News) session.get(News.class, 21); 86 System.out.println(news); 87 session.refresh(news); 88 System.out.println(news); 89 } 90 91 /** 92 * clear():清理緩存 93 */ 94 @Test 95 public void testClear() { 96 News news1 = (News) session.get(News.class, 21); 97 session.clear(); 98 News news2 = (News) session.get(News.class, 21); 99 }100 }新聞熱點
疑難解答