Hibernate的缓存
二级缓存:Hibernate 提供了基于应用程序级别的缓存称为二级缓存,可以跨过多个session,即是不同的session都可以访问缓存数据,这个缓存也叫二级缓存。
Hibernate提供的二级缓存有默认的实现,且是一种可以插配的缓存的框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置既可;不想用的话,直接的移除,不影响代码,如果用户觉得hibernate提供的框架不好用的话,自己可以换其他的缓存框架或者自己实现缓存框架都可以。
1.1查看hibernate.properties配置文件,二级缓存如何配置????
#########################
#########Second-level Cache
#########################
#hibernate.cache.use_second_level_cache false[二级缓存默认不开启,需要手动开启]
#hibernate.cache.use_query_cache true [开启查询缓存]
##choose a cache implementation[二级缓存框架的实现]
#hibernate.cache.provider_class org.hibernate.cache.EhcacheProvider
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider 默认的实现
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider
1.2:二级缓存,使用步骤,
1)开启二级缓存;
2)指定缓存框架
3)指定那些类加入二级缓存
4)测试
<!--***************************[二级缓存配置]*******************-->
<!----a. 开启二级缓存---->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--b.指定使用那个缓存框架(默认提供的)-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!--开启查询的缓存-->
<property name="hibernate.cache.use_quey_cache">true</property>
<!----c 指定哪一些类,需要加入二级缓存-->
<class-cache usage="read-write" class="com.bie.lesson11.Dept"/>
<class-cache usage="read-only" class="com.bie.lesson11.Employee"/>
<!-集合缓存(集合缓存的元素对象,也加入二级缓存)->
<collection-cache usage="read-write" collection="com.bie.lession11.Dept.emps"/>
1.3缓存策略:
<class-cache usage="read-only"/>放入二级缓存的对象,只读
<class-cache usage="nonstrict-read-write"/>非严格的读写
<class-cache usage="read-write"/>读写,放入二级缓存对象可以读,写
<class-cache usage="transactionl"/>基于事务的策略
2.1Hibernate 的一级缓存
2.1.1:使用一级缓存的目的是为了减少对数据库的访问次数,从而提升hibernate的执行的效率(当执行一次查询操作的时候,先检查缓存中是否有数据,如果有数据就不查数据库,直接从缓存中取得数据。。
2.1.2Hibernate的一级缓存,也叫做session缓存,它可以在session中范围内减少数据库的访问次数,只在session范围内有效,session关闭,一级缓存失败。。
2.1.3一级缓存的特点,只在session内有效,作用的时间短,效果不是特别的明显,在短时间内多次的操作数据库,效果比较明显。
2.1.4当调用session的save/saveOrUpdate/get/load/list/itertor方法的时候,都会把对象放入session缓存中。
2.1.5session的缓存是在hibernate维护的,用户不能操作缓存内容,如果想操作缓存内容,必须通过hibernate提供的evict/clear方法操作。。
2.1.6缓存相关的方法(在什么情况下使用上边的方法呢,如session.flush();先与数据库同步,session.clear():再清空一级缓存内容)
session.flush();让一级缓存与数据库同步
session.evict();清空一级缓存中指定的对象
session.clear()清空一级缓存中的所有的对象
2.1.7面试题
不同的session是否共享缓存数据?
答案:不会的啊
2.1.8 list和iterator的区别?
(1)list查询
答:一次性的把所有的记录都查询出来了,会放入缓存,不会从缓存中取得数据的。
(2)iterate(N+1次查询)
答:N表示所有的记录总数;即会发送一条语句查询所有的记录的主键,这是第一条查询,再根据每一个主键去数据库查询,这是根据第一次查询的条数进行N次查询操作,会放入缓存,也会从缓存中取得数据。。。
2.1.9 Hibernate的懒加载
2.1.10:懒加载的概念,当用到数据的时候,才向数据库查询,这就是hibernate的懒加载特性。
使用懒加载的目的:是提高程序的执行效率。。。
查询操作:get()方法/load()方法
get()方法,及时加载,及时的查询操作,只要调用get方法就立刻的向数据库查询。。。
load()方法,默认懒加载,即是在使用数据库的时候,才向数据库发送查询的sql语句,session关闭以后,不可以使用懒加载。。。
#懒加载默认为true,即是懒加载,即lazy="false"
#lazy="false"关闭懒加载
#lazy="true"使用懒加载
#lazy="extra"在真正使用数据的时候才向数据库发送查询的sql语句,集合属性懒加载的时候提升效率,如果调用集合的size()/isEmpty()方法只是统计,不是真正的查询。。
<class name="类名称" table="数据表名称" lazy="false">
</class>
2.1.11 懒加载异常
Session关闭后,不能使用懒加载数据,如果session关闭后,使用懒加载数据报错如下:
如何解决session关闭后不能使用懒加载加载数据的问题:
方式一:可以先在关闭session之前使用一下数据,这样关闭以后就可以使用此数据了。如Dept.getDeptName();
方式二(推荐):强迫代理对象初始化操作:Hibernate.initialize(对象);
方式三:关闭懒加载(lazy="false");
方式四(推荐):在使用数据之后再关闭session;