什么是一级缓存
Hibernate的一级缓存就是指session缓存。当Hibernate查询对象时,会先通过oid属性查询一级缓存,若一级缓存中存在对象,则直接从一级缓存中取出该对象。若一级缓存中不存在则从数据库中查找,从数据库中查找到数据,该数据也会放置到一级缓存当中。
一级缓存的作用就是减少对数据库的访问次数,提高效率
证明一级缓存的存在
@Test
//证明一级缓存的存在,若一级缓存存在获取多个对象只会打印一个sql语句,并输出结果为true,证明他们是同一个对象
public void test(){
Session s = HibernateUtils.openSession();
Transaction t = s.beginTransaction();
Customer c = new Customer();
Customer customer = s.get(Customer.class, 1l);
Customer customer2 = s.get(Customer.class, 1l);
//输出结果为true
System.out.println(customer==customer2);
t.commit();
s.close();
}
一级缓存的内部结构 快照区
Hibernate向一级缓存中写入数据时,会同时复制一份数据到一级缓存中的快照区。当事务使用commit()方法提交时,同时会清理一级缓存。这时会通过oid进行查询属性,若一级缓存中的属性与快照区的属性不同,则使用update()方法进行更新,然后再写入数据库。如相同则不执行update()方法
快照区的作用是确保Hibernate的数据与数据库的数据一致
证明快照的存在1
//证明快照的存在,最终修改的值等于快照的值,那它就不会打印sql语句update数据
@Test
public void test2(){
Session s = HibernateUtils.openSession();
Transaction t = s.beginTransaction();
Customer c = s.get(Customer.class,1l);
c.setCust_name("快照中不存在的数据");
//我数据库中oid为1L的数据name为“联想”
c.setCust_name("联想");
t.commit();
s.close();
}
证明快照的存在2
@Test
//无论如何都会打印update语句,因为经过数据库返回才有快照,这里快照和以及缓存不一致
public void test3(){
Session s = HibernateUtils.openSession();
Transaction t = s.beginTransaction();
Customer c = new Customer();//瞬时状态
c.setCust_id(1l);//游离态
s.update(c); //持久态
Customer c2 = s.get(Customer.class, 1l);
t.commit();
s.close();
}