一级缓存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();
}
}