SSH系列:Hibernate中的一級快取和快照
阿新 • • 發佈:2019-01-05
一級快取session:執行緒級別。 二級快取:程序級別
快照:
1、快照是資料的副本
2、快照屬於一級快取
3、快照是在堆記憶體中的
4、快照的作用:保證資料一致性
5、快照的理解:當執行session.getTransaction().commit()時,
Hibernate同時會清理session的一級快取(flush),
也就是將堆記憶體中的資料與快照中的資料進行對比,如果不一致,則會執行同步(update)操作,
若相同,則不執行update。
舉個栗子:
例1、如下程式碼的執行過程就是如圖所示的執行過程,呼叫session.get()方法獲取user物件是持久態,堆區存在一級快取和快照。
@Test public void testCache1() { Session session = hibernateUtils.getOpenSession(); User u1 = (User) session.get(User.class,1); //持久態:有快取,且有快照 //u1.setUsername(""); session.update(u1); session.beginTransaction().commit(); session.close(); }
例2、如下程式碼的執行過程就是如圖所示的執行過程,用new User()方法獲取user物件是瞬時態,當執行session.update()時,物件轉成持久態,堆區只存在一級快取。
@Test public void testCache2() { Session session = hibernateUtils.getOpenSession(); User u1 = new User(); //瞬時態 u1.setUsername("張三"); session.update(u1); //有快取,但沒有快照 session.beginTransaction().commit(); session.close(); }
3、如下案例根據sql語句的列印次數,判斷存不存在一級快取。
package hibernate;
import static org.junit.Assert.*;
import java.util.List;
import hibernateUtils.hibernateUtils;
import org.hibernate.Session;
import org.junit.Before;
import org.junit.Test;
public class TestCache {
@Test
/*三條查同一個id的語句,只會查詢一次資料庫,然後放進一級快取session中,
第二第三次呼叫get方法就不會再查資料庫,直接從一級快取中取出
*/
public void testCache() {
Session session = hibernateUtils.getOpenSession();
User u1 = (User) session.get(User.class,1);
User u2 = (User) session.get(User.class,1);
User u3 = (User) session.get(User.class,1);
System.out.println(u1);
session.close();
}
@Test
//hql:查詢語句一共輸出三次,所以hql沒有快取,更沒有快照
public void testCache3() {
Session session = hibernateUtils.getOpenSession();
List<User> list = session.createQuery("from User").list();
List<User> list1 = session.createQuery("from User").list();
List<User> list2 = session.createQuery("from User").list();
session.close();
}
@Test
//hql:createQuery 下面再呼叫Get方法就存在快取了
public void testCache4() {
Session session = hibernateUtils.getOpenSession();
List<User> list = session.createQuery("from User").list(); //列印select資料庫的語句
User u1 = (User) session.get(User.class,1); //不列印sql語句,也就是沒有查詢資料庫,說明有快取
session.close();
}
@Test
//查詢語句一共輸出三次,所以createCriteria沒有快取
public void testCache5() {
Session session = hibernateUtils.getOpenSession();
List<User> list = session.createCriteria(User.class).list();
List<User> list1 = session.createCriteria(User.class).list();
List<User> list2 = session.createCriteria(User.class).list();
session.close();
}
@Test
//查詢語句一共輸出三次,所以createSQLQuery沒有快取
public void testCache6() {
Session session = hibernateUtils.getOpenSession();
List list = session.createSQLQuery("select * from t_user").list();
List list1 = session.createSQLQuery("select * from t_user").list();
List list2 = session.createSQLQuery("select * from t_user").list();
session.close();
}
@Test
//查詢語句一共輸出三次,所以createCriteria沒有快取
public void testCache7() {
Session session = hibernateUtils.getOpenSession();
List<User> list = session.createSQLQuery("select * from t_user").addEntity(User.class).list();
List<User> list1 = session.createSQLQuery("select * from t_user").addEntity(User.class).list();
List<User> list2 = session.createSQLQuery("select * from t_user").addEntity(User.class).list();
session.close();
}
}