hibernate的缓存机制对应于两种缓存:session中的一级缓存,sessionFactoury中的二级缓存。

  缓存中的对象存在内存,如果数据量大大得时候,可以存在硬盘。

 

1.session缓存实现原理

 实现原理:Session缓存是由它的实现类SessionImpl中定义的一些集合属性构成的,原理是保证有一个引用在关联着某个持久化对象,保持它的生命周期不会结束。这样说来,

当我们User user=new User(),然后对user数值值赋值,使它对应数据库一条记录,但是由于其没有与session相关联,即session中没有引用关联这个对象,所以它是托管状态的。

 

2,使用flush清理缓存

   1)使用flush()可以清理掉缓存。但是一般不显示调用,显示调用会浪费系统资源(与数据库交互),一般由hibernate自己维护,尽量延迟到最后调用它。

   2)

session.save(user);
        session.save(student)
        session.save(employee)
       System.out.println("=======");
        transaction.commit();

一般情况下事务提交的时候,hibernate才会调用flush()方法清理掉缓存。控制台显示sql语句:

Hibernate: insert into user(name, dept_id, id) values(?, ?, ?)
 =======   
 Hibernate: insert into student(name, dept_id, skill, id) values(?, ?, ?, ?)
   Hibernate: insert into employee(name, dept_id, sell, id) values(?, ?, ?, ?)

原因解释:

先打印=======,说明在提交的时候,hibernate才清理缓存,将缓存中的数据与数据库中同步。但是为什么对user的插入出现在======之前呢?

这是因为user的主键是自增长的,user必须保存之后才能拿到主键。

 

3,缓存的作用

   1)更新对象时,减少与数据库打交道的次数

从上面的例子可以知道,缓存的存在,可以使对象的改变存在缓存中,当使用flush清理缓存时,可以对对象的所有改变进行批量操作(与数据库打一次交道),减少与数据库打交道的次数。

  2)查询对象时,减少与数据库打交道的次数

Customer c1 = (Customer)session.get(Customer.class, 1L);  
Customer c2 = (Customer)session.get(Customer.class, 1L);

hibernate比较聪明,由于缓存中有此对象了,所以第二次get()时不会从数据库中查询,而是直接使用缓存中的对象。(注意缓存要定时清理,与数据库同步)

 

 

 


Session清理缓存的时间点


Session通过setFlushMode()方法来设置清理缓存的时间点。FlushMode类定义了三种不同的清理模式:FlushMode.AUTO、FlushMode.COMMIT、FlushMode.NEVER


无论设置为哪种FulshMode,当session.flush()时,都会清理缓存。


若设置为FulshMode.NEVER,则即便transaction.commit()也不清理缓存,只能通过session.flush()来清理。


若设置为FulshMode.AUTO,则session.find(),session.iterate()(),transaction.commit(),session.flush()都将清理缓存。


所以,优先考虑使用FlusthMode.AUTO,这也是默认值。这也就是说大部分时候,无须手动执行session.flush()。