Session中的缓存可以理解为一个Hibernate应用中处于持久状态对象的集合。当Session的load方法视图从数据库中加载某个对象时,Session会先判断在缓存中是否已经存在这个对象了,如果存在就不需要到数据库中进行检索。只要Session的缓存没有被清空,持久对象的生命周期便没有结束。
Session中的缓存清空与缓存的清理是两个概念。缓存清空是指将缓存内的持久对象进行清除,持久对象在缓存清空之后便结束了其生命周期,一般在调用close()和clear()等方法的时候进行缓存的清空。
Session的缓存的清理是指每隔一段时间,Session执行SQL语句的时候将内存中的对象的状态同步到JDBC链接中。一般默认调用org.hiberbate.Transaction.commit()方法、Session的flush()方法以及执行某些查询的时如:find()和iterate()方法进行清理。
注意的是,如果使用标示方法是native,那么在调用save()方法的时候会立即执行insert语句。
Session.flush()操作进行缓存清理时,会执行上述SQL语句,但是不会提交事务。Transaction.commit()方法会先执行flush()方法,然后提交事务。
除了默认的时间点进行缓存的清理之外,也可以改变默认的设置,来控制清理操作的发生频率。
FlushMode类定义了三种不同的方式,可以通过Session.setFlushMode()方法进行设置。
1.FlushMode.AUTO:于默认的清理方式相同。
2.FlushMode.COMMIT:在执行commit方法和flush方法时进行清理。
3.FlushMode.NEVER:除非显示的调用flush方法,否则从不进行清理,这种方式对于那些需要长时间保持在session中为打开或者断线状态的长时间运行的应用程序很有用。
持久化对象的cascade级联操作:
none:
save-update:(针对的是当对当前对象进行save或update操作时,要对想关联的对象进行save和update操作)
all:(包含如下所有情况delete,save-update)
delete:级联删除
delete-orphan:删除所有和当前对象解除关联关系的对象。
all-delete-orphan:级联删除delete,也包含级联save-update、delete-orphan
Hibernate的二级缓存
Hibernate的缓存包括两类,分别是session和SessionFactory的缓存。SessionFactory的缓存有可以分为两类:内置缓存和外置缓存。Session的缓存时内置的,无法被卸载。通常Hibernate的一级缓存。SessionFactory的内置缓存和Session的缓存在实现方式上比较相似。前者是SessionFactory对象的一些集合属性包含的数据,存放了映射元数据和预定义SQL语句,其中映射元数据是映射文件中数据的拷贝。预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来的。SessionFactory不需要进行内置缓存与映射文件的同步,因为SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句。后者则是指Session的一些集合属性包含的数据。可以这样理解,SessionFactory的内置缓存保存的是Hibernate底层需要的一些配置、映射文件、SQL语句等信息是公共级的。而Session的内置缓存也就是Hibernate的一级缓存保存的是应用程序所需要的一些配置、对象等信息是应用级的。
SessionFactory的外置缓存时一个可配置的插件。在默认情况下SessionFactory不会启用这个插件,他也被称为Hibernate的二级缓存。外置缓存的数据是数据库的拷贝,外置缓存的介质可以是内存或者是硬盘。
持久化层可以提供多种范围的缓存。如果事务范围中没有查到相应的数据,还可以到进程范围或集群范围的缓存内查询,如果还是没有查到,那么只有到数据库中查询。事务范围的缓存时持久化层的第一级缓存,通常它是必须的;进程范围或集群范围的缓存时持久化层的第二级缓存,通常是可选的。
二级缓存位于内存或者是硬盘中,有可能出现并发的问题。因此需要适当的并发策略。该策略为被缓存的数据提供事务隔离级别。