hibernate 一级和二级缓存使用总结
hibernate的缓存分为一级缓存和二级缓存,一级二级和我们常说的cpu的一级二级是不一样的。这里的一级说的是session的缓存,是hibernate内置的,不能卸载。二级说的是SessionFactory中的外置缓存,SessionFactory的内置缓存是放映射数据和sql语句的,程序不能更改,也不算二级缓存。二级缓存可以配置和更改,并且动态加载和卸载。Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。
二.一级缓存的管理:当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的list()、iterate()或filter()方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。Session为应用程序提供了两个管理缓存的方法:evict(Objectobj):从缓存中清除参数指定的持久化对象。clear():清空缓存中所有持久化对象。
三.Hibernate二级缓存的管理:
1.Hibernate二级缓存策略的一般过程如下:
1)条件查询的时候,总是发出一条select*fromtable_namewhere….(选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。
2)把获得的所有数据对象根据ID放入到第二级缓存中。
3)当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4)删除、更新、增加数据的时候,同时更新缓存。Hibernate二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的QueryCache。
2.什么样的数据适合存放到第二级缓存中?
1)很少被修改的数据
2)不是很重要的数据,允许出现偶尔并发的数据
3)不会被并发访问的数据
4)参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用,实例极少或者从来不会被修改。
3.不适合存放到第二级缓存的数据?
1)经常被修改的数据
2)财务数据,绝对不允许出现并发
3)与其他应用共享的数据。
4.常用的缓存插件Hibernater二级缓存是一个插件,下面是几种常用的缓存插件:
◆EhCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
◆OSCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
◆SwarmCache:可作为群集范围内的缓存,但不支持Hibernate的查询缓存。
◆JBossCache:可作为群集范围内的缓存,支持事务型并发访问策略,对Hibernate的查询缓存提供了支持。
◆memcached
◆redis
四、如何配置二级缓存
4.1如果采用ehcached,配置如下:
4.1.1将相应的二级缓存组件jar包导入到classpath类路径下
4.1.2在hibernate.cfg.xml文件中配置如下的信息:
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<propertyname="hibernate.cache.use_query_cache">true</property>
<propertyname="cache.use_second_level_cache">true</property>
<propertyname="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
4.1.3.指定哪些对象选要被缓存:这里既可以在hibernate.cfg.xml文件中配置,也可以在对应的hbm文件中配置
4.1.3.1hibernate.cfg.xml文件中配置如下:
指定需要缓存的对象类型:这里可以在映射文件中配置,也可以在hibernate核心配置文件中进行配置
<class-cacheclass="com.hib.entity.Inf"usage="read-only"/>
4.1.3.2hbm文件中配置如下:
<cacheusage="read-only"/>在需要缓存的元素下添加<cache>元素,根据需求使用相应的缓存级别
4.1.4.在src目录下编写一个ehcache.xml文件,配置一些基本的缓存信息:
一般配置信息如下:
<?xmlversion="1.0"encoding="utf-8"?>
<ehcache>
<diskStorepath="D:/ehcache"/><!--如果缓存中的对象存储超过指定的缓存数量的对象存储的磁盘地址-->
<!--全部默认的配置
maxElementsInMemory在內存中最多存放多少个对象
eternal对象是不是永远不变的,一般都是false
timeToLiveSeconds如果这个对象超过了这个时间,就会从缓存中清除
-->
<defaultCache
maxElementsInMemory="500"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<!--针对指定的对象使用的缓存配置
name表示的是缓存的类对象的全路径名-->
<cachename="com.hibernate.Student"
maxElementsInMemory="500"
eternal="false"
timeToIdleSeconds="50"
timeToLiveSeconds="50"
overflowToDisk="true"
/>
</ehcache>
4.1.3.5如果有spring,那么spring中的配置
4.1.3.5.1.在类路径上ehcache.xml:
<ehcache>
<!--Setsthepathtothedirectorywherecache.datafilesarecreated.
IfthepathisaJavaSystemPropertyitisreplacedby
itsvalueintherunningVM.
Thefollowingpropertiesaretranslated:
user.home-User'shomedirectory
user.dir-User'scurrentworkingdirectory
java.io.tmpdir-Defaulttempfilepath-->
<diskStorepath="java.io.tmpdir"/>
<!--DefaultCacheconfiguration.Thesewillappliedtocachesprogrammaticallycreatedthrough
theCacheManager.
Thefollowingattributesarerequired:
maxElementsInMemory-Setsthemaximumnumberofobjectsthatwillbecreatedinmemory
eternal-Setswhetherelementsareeternal.Ifeternal,timeoutsareignoredandthe
elementisneverexpired.
overflowToDisk-Setswhetherelementscanoverflowtodiskwhenthein-memorycache
hasreachedthemaxInMemorylimit.
Thefollowingattributesareoptional:
timeToIdleSeconds-Setsthetimetoidleforanelementbeforeitexpires.
i.e.Themaximumamountoftimebetweenaccessesbeforeanelementexpires
Isonlyusediftheelementisnoteternal.
Optionalattribute.Avalueof0meansthatanElementcanidleforinfinity.
Thedefaultvalueis0.
timeToLiveSeconds-Setsthetimetoliveforanelementbeforeitexpires.
i.e.Themaximumtimebetweencreationtimeandwhenanelementexpires.
Isonlyusediftheelementisnoteternal.
Optionalattribute.Avalueof0meansthatandElementcanliveforinfinity.
Thedefaultvalueis0.
diskPersistent-WhetherthediskstorepersistsbetweenrestartsoftheVirtualMachine.
Thedefaultvalueisfalse.
diskExpiryThreadIntervalSeconds-Thenumberofsecondsbetweenrunsofthediskexpirythread.Thedefaultvalue
is120seconds.
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/>
<!--Seehttp://ehcache.sourceforge.net/documentation/#mozTocId258426forhowtoconfigurecachingforyourobjects-->
</ehcache>
4.1。3.5.2.applicationContext-hibernate.xml里HibernateSessionFactory配置:
<!--HibernateSessionFactory-->
<beanid="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="configLocation"><value>classpath:hibernate.cfg.xml</value></property>
<!--Thepropertybelowiscommentedoutb/citdoesn'tworkwhenrunvia
AntinEclipse.ItworksfineforindividualJUnittestsandinIDEA??
<propertyname="mappingJarLocations">
<list><value>file:dist/appfuse-dao.jar</value></list>
</property>
-->
<propertyname="hibernateProperties">
<props>
<propkey="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
<!--<propkey="hibernate.show_sql">true</prop>-->
<propkey="hibernate.max_fetch_depth">3</prop>
<propkey="hibernate.hibernate.use_outer_join">true</prop>
<propkey="hibernate.jdbc.batch_size">10</prop>
<propkey="hibernate.cache.use_query_cache">true</prop>
<propkey="hibernate.cache.use_second_level_cache">true</prop>
<propkey="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<!--
<propkey="hibernate.use_sql_comments">false</prop>
-->
<!--Create/updatethedatabasetablesautomaticallywhentheJVMstartsup
<propkey="hibernate.hbm2ddl.auto">update</prop>-->
<!--TurnbatchingoffforbettererrormessagesunderPostgreSQL
<propkey="hibernate.jdbc.batch_size">0</prop>-->
</props>
</property>
<propertyname="entityInterceptor">
<reflocal="auditLogInterceptor"/>
</property>
</bean>
启用class缓存:
4.2其他缓存和spring也是差不多,基本上是导包,自身缓存配置,spring配置加上true.