日期:2014-05-17  浏览次数:20627 次

hibernate持久化类和一级缓存的关系?
最近学习hibernate框架,看到hibernate对象的状态和 session的一级缓存的机制有点异曲同工之妙。



而同时
关于session的缓存又有下面一段话
怎么样把数据存放到一级缓存中?
        利用session.save/update/load/get方法都可以存放在一级缓存中
session.evict方法可以把一个对象从一级缓存中清空?
        利用session.clear方法可以把session中的所有的数据清空

让我实在是不得不怀疑所谓的持久化状态就是放在一级缓存中。

好了问题来了,一级缓存的生命周期就是session的生命周期,当session关闭的时候,相对应的一级缓存中的数据也就消失了,那么看下面这个例子。


@Test
public void test(){
Session session = sessionFactory.openSession();
// Transaction transaction = session.beginTransaction();
// Person p1 =(Person)session.load(Person.class, 1L);
Person p1 =(Person)session.get(Person.class, 1L);
// transaction.commit();
session.close();
System.out.println(p1.getPsex());
}
        OUTPUT:nan 成功输出
        我不禁疑惑,这个p1到底有没有放在一级缓存中?
        如果有,session 关闭后为什么还能使用?
        如果没有,首先确定没关闭之前是放在一级缓存中,那么关闭之后缓存消失,它跑哪里去了?
        
------解决方案--------------------
我一直以来都是这样认为的:缓存不是内存,缓存你可以把它看成一个寄存器,对象在session关闭后 变为游离态,然后在内存中放着而已
------解决方案--------------------
我觉得你没有理解什么缓存。
抛开hibernate不说,什么是缓存?是一种为了提高数据读取效率的一种介质。是介质,缓存的数据是拷贝而来的。你明白了这一点,再给你说你第二个问题,
Person p1 =(Person)session.get(Person.class, 1L);
这句代码,直接就持久化了p1对象,就是说执行了SQL查询,很明显你还没理解持久化的概念,
说白了,持久化就是数据库有,sesison缓存也有。
你已经用一个实体对象p1接受了你查询的对象,那么你下面打印当然有东西,你system语句打印的又不是你缓存的东西,可以说和你的缓存毫无关系啊。缓存本身就是拷贝来的数据,你打印的是你持久化的对象,二者毫不相干,明白了吧。