Hibernate part 7:Session 一级缓存

在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 存放在它缓存中的对象也不会结束生命周期

一级缓存是存在的,通过get()查询Customer对象,查询两次ID为1的Customer对象,控制台只发送了一条SQL,并且打印c1和c2,获得的地址是一样的,可以证明Session缓存是存在的

@Test
	public void testSessionExist() {
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		
		Customer c1 = (Customer) session.get(Customer.class, 1);
		System.out.println(c1);
		
		Customer c2 = (Customer) session.get(Customer.class, 1);// 再次执行查询,直接使用一级缓存中数据
		System.out.println(c2);
		
		transaction.commit();
		session.close();
	}

Session缓存和快照的存储原理

@Test
	public void testSession02() {
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		
		Customer c = (Customer) session.get(Customer.class, 1); //persistent状态对象
		c.setName("孙艺珍");	//修改一级缓存中的数据
		//session.save(c); //不调用save()方法
		
		transaction.commit();
		session.close();
	}

 在没有调用save()情况下,程序依然更新了ID为1的Customer对象
Hibernate part 7:Session 一级缓存
 
  代码层面关闭事物,在hibernte.cfg.xml中配置hibernate.connection.autocommit事物自动提交,但数据然仍没有被修改,只有flush()后才会去比较一级缓存和快照区数据是否一致,commit()中已经调用flush()了

@Test
	public void testSession02() {
		Session session = HibernateUtils.openSession();
		
		Customer c = (Customer) session.get(Customer.class, 1); //persistent状态对象
		c.setName("孙艺珍");	//修改一级缓存中的数据
                session.flush();
		//session.save(c); //不调用save()方法
		
		session.close();
	}
 

默认情况下 Session 在以下时间点刷出缓存:

  • 当应用程序调用 Transaction 的 commit()方法的时, 该方法先刷出缓存(session.flush()),然后在向数据库提交事务(tx.commit())
  • 当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会先刷出缓存,以保证查询结果能够反映持久化对象的最新状态
  • 调用 Session 的 flush() 方法

相关推荐