hibernate 快取介紹與快取使用方式
hibernate中提供了兩級快取,一級快取是Session級別的快取,它屬於事務範圍的快取,該級快取由hibernate管理,應用程式無需干預;二級快取是SessionFactory級別的快取,該級快取可以進行配置和更改,並且可以動態載入和解除安裝,hibernate還為查詢結果提供了一個查詢快取,它依賴於二級快取;
一,快取的概念
快取是位於應用程式和永久性資料儲存源之間用於臨時存放複製資料的記憶體區域,快取可以降低應用程式之間讀寫永久性資料儲存源的次數,從而提高應用程式的執行效能;
hibernate在查詢資料時,首先會到快取中查詢,如果找到就直接使用,找不到時才從永久性資料儲存源中檢索,因此,把頻繁使用的資料載入到快取中,可以減少應用程式對永久性資料儲存源的訪問,使應用程式的執行效能得以提升;
二,快取的範圍
快取範圍決定了快取的生命週期,快取範圍分為3類:
1>事務範圍
快取只能被當前事務訪問,快取的生命週期依賴於事務的生命週期,事務結束時,快取的生命週期也結束了;
2>程序範圍
快取被程序內的所有事務共享,這些事務會併發訪問快取,需要對快取採用必要的事務隔離機制,快取的生命週期取決與程序的生命週期,程序結束,快取的生命週期也結束了;
3>叢集範圍
快取被一個或多個計算機的程序共享,快取中的資料被複制到叢集中的每個進行節點,程序間通過遠端通訊來保證快取中資料的一致性;
在查詢時,如果在事務範圍內的快取中沒有找到,可以到程序範圍或叢集範圍的快取中查詢,如果還沒找到,則到
三,Hibernate中的第一級快取
Hibernate的一級快取由Session提供,只存在於Session的生命週期中,當應用程式呼叫Session介面的save(),update(),saveOrupDate(),get(),load()或者Query和Criteria例項的list(),iterate()等方法時,如果Session快取中沒有相應的物件,hibernate就會把物件加入到一級快取中,當session關閉時,該Session所管理的一級快取也會立即被清除;
1,get查詢測試:
1>在同一個session中發出兩次get查詢
- <span style="font-size:18px;"><strong> publicvoid Query(){
- Session sess = HibernateSessionFactory.getSession();
- Transaction tx = sess.beginTransaction();
- Student s1 = (Student)sess.get(Student.class, 2);
- System.out.println(s1.getName());
- Student s2 = (Student)sess.get(Student.class, 2);
- System.out.println(s2.getName());
- tx.commit();
- HibernateSessionFactory.closeSession();
- }</strong></span>
2>開啟兩個session中發出兩次get查詢
[java] view plain copy print?- <span style="font-size:18px;"><strong> publicvoid Query(){
- Session sess1 = HibernateSessionFactory.getSession();
- Transaction tx1 = sess1.beginTransaction();
- Student s1 = (Student)sess1.get(Student.class, 2);
- System.out.println(s1.getName());
- tx1.commit();
- HibernateSessionFactory.closeSession();
- Session sess2 = HibernateSessionFactory.getSession();
- Transaction tx2 = sess2.beginTransaction();
- Student s2 = (Student)sess2.get(Student.class, 2);
- System.out.println(s2.getName());
- tx2.commit();
- HibernateSessionFactory.closeSession();
- }</strong></span>
2,iterate查詢測試
插入一個iteritor查詢方式:
[java] view plain copy print?- <span style="font-size:18px;"><strong> publicvoid Query(){
- Session sess = HibernateSessionFactory.getSession();
- Transaction tx = sess.beginTransaction();
- Query query = sess.createQuery("from Student");
- Iterator iter = query.iterate();
- while(iter.hasNext()){
- System.out.println(((Student)iter.next()).getName());
- }
- tx.commit();
- HibernateSessionFactory.closeSession();
- }</strong></span>
- <span style="font-size:18px;"><strong> publicvoid Query(){
- Session sess = HibernateSessionFactory.getSession();
- Transaction tx = sess.beginTransaction();
- Student s1 = (Student)sess.createQuery("from Student s where s.id = 2").iterate().next();
- System.out.println(s1.getName());
- Student s2 = (Student)sess.createQuery("from Student s where s.id = 2").iterate().next();
- System.out.println(s2.getName());
- tx.commit();
- HibernateSessionFactory.closeSession();
- }</strong></span>
3,iterate查詢屬性測試:
[java] view plain copy print?- <span style="font-size:18px;"><strong> publicvoid Query(){
- Session sess = HibernateSessionFactory.getSession();
- Transaction tx = sess.beginTransaction();
- String name1 = (String)sess.createQuery("select s.name from Student s where s.id = 2").iterate().next();
- System.out.println(name1);
- String name2 = (String)sess.createQuery("select s.name from Student s where s.id = 2").iterate().next();
- System.out.println(name2);
- tx.commit();
- HibernateSessionFactory.closeSession();
- }</strong></span>
4,在一個session中先save,再執行load查詢
[java] view plain copy print?- <span style="font-size:18px;"><strong> publicvoid Query(){
- Session sess = HibernateSessionFactory.getSession();
- Transaction tx = sess.beginTransaction();
- Student s = new Student(8, "newAcc", 8, 8);
- Serializable id = sess.save(s);
- tx.commit();
- Student s1 = (Student)sess.load(Student.class, 8);
- System.out.println(s1.getName());
- HibernateSessionFactory.closeSession();
- }</strong></span>
--------------------
Session介面為應用程式提供了兩個管理快取的方法:
1>evict()方法:用於將某個物件從Session的一級快取中清除;
2>clear()方法:用於將一級快取中的所有物件全部清楚;
測試:
[java] view plain copy print?- <span style="font-size:18px;"><strong> publicvoid Query(){
- Session sess = HibernateSessionFactory.getSession();
- Transaction tx = sess.beginTransaction();
- Student s = (Student)sess.load(Student.class, 1);
- System.out.println(s.getName());
- sess.clear();//清除一級快取中的所有物件
- Student s1 = (Student)sess.load(Student.class, 1);
- System.out.println(s1.getName());