Hibernate做为和数据库数据打交道的框架,天然会设计到操做数据的效率wenti,而对于一些频繁操做的数据,缓存策略就是提升其性能一种重要手段,而Hibernate框架是支持缓存的,并且支持一级和二级两种缓存,合理的使用缓存策略能够大大提升咱们的操做数据效率,可是利用不能,可能会形成没必要要的麻烦。 web
一,一级缓存(Session缓存): spring
Session缓存表示将查询结果放置到Session的临时存储空间(一级缓存中)。Hibernate框架默认支持一级缓存的。一级缓存的范围较小,一旦Session关闭,那么缓存失效。咱们使用框架的各类方法,例如:get,load,save,update,delete等都支持一级缓存的。 数据库
二,二级缓存(SessionFactory缓存): 编程
1,概述:二级缓存其实就是将查询的数据放置在SessionFactory临时存储空间中,由于一个SessionFactory能够建立多个Session对象,因此范围比Session缓存的要大,多个Session能够共享二级缓存的数据。固然了二级缓存也不能存储大量的数据,这个要根据咱们电脑配置进行设置。 缓存
2,如何设置使用二级缓存呢?Hibernate默认是不支持二级缓存的。 安全
a,首先在hibernate.cfg.xml配置文件中添加属性标签,启用二级缓存: 服务器
<!--启用二级缓存 --> session
<propertyname="hibernate.cache.use_second_level_cache">true</property> app
b,二级缓存须要使用额外的第三方组件:ehcache。须要咱们拷入对应的jar包,以及将对应的ehcache.xml存放到src目录下。在这个配置文件中,咱们能够设置二级缓存的大小等。 框架
c,让框架识别添加入的ehcache缓存组件,在hibernate.cfg.xml配置文件中添加属性标签:
<!--让框架识别ehcache缓存组件 -->
<propertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
d,设置须要缓存的映射类,这里只是将一些查询操做比较频繁的类指定便可,哪些不常常操做的数据,是没有必要利用缓存的。这里例如:
<!-- 将指定的类存放到二级缓存中,其中read-only是指放入缓存的数据是只读的-->
<class-cache usage="read-only" class="com.ljh.hibernate.pojo.Student"/>
3,缓存的操做数据原理:
查询数据时,会首先从一级缓存中取数据,若是取上,则直接使用,不然到二级缓存中取,若是取到则直接使用,不然,就会发送语句查询数据库。这样利用一级和二级缓存会提升访问效率。
固然使用二级缓存要慎重,要考虑数据的操做频繁性,服务器的硬件配置,数据的安全性等等方面,这样才能很好的利用二级缓存,提升咱们操做数据的效率,不然使用不当就会带来没必要要的麻烦。
三,Lazy(懒加载)
1,lazy(Hibernate的延迟加载功能):表示查询当前对象或关联对象数据时,不真正访问数据库,当使用对象非主键属性时,才真正发送查询语句,访问数据库。因为在某些状况下,查的数据在后续流程到可能用不上,若是作查询处理就多余了,因此延迟加载功能能够提升性能,合理使用便可。固然了Hibernate框架是经过Cglib代理来完成延迟加载功能的扩展的。
2,用到lazy地方总结,这里只是对类和映射的地方简单总结了一下,在实际运用中咱们还要学会恰当的选择:
标签 |
起做用到什么地方 |
取值解释 |
<class> |
针对load方法 |
true : 延迟加载 (默认) false : 禁用延迟加载 |
<set> |
针对于一对多,多对多 |
true : 延迟加载 (默认) false : 禁用延迟加载 extra : 支持延迟加载,在访问集合自身信息时能够发送高效的查询语句。(推荐) |
<many-to-one> |
针对于多对一,一对一 |
false : 禁用延迟加载 proxy : 延迟加载 (默认) no-proxy : 支持延迟加载,不使用cglbi代理的方式完成延迟加载。经过第三方的字节码加强工具。 |
<one-to-one> |
针对一对一 |
和<many-to-one>标签同样,这里须要注意: 一对一的主键关联映射,根据主动方(不含外键)查询被动方(既是主键,又是外键)时不支持延迟加载的。 |
3,遇到的wenti:lazy,延迟加载功能是运用的一级缓存,也就是利用的是session的内存,通常状况下,咱们在用完session后会进行关闭,可是关闭后咱们就没法进行延迟查询数据了,也就是说,延迟加载功能就将失效,剖出异常:No Sesssion,因此这是须要咱们解决的。
4.NoSession异常的解决:
a,解决原理:咱们能够在dao层不进行session的关闭,经过前边学习的AOP编程思想,添加过滤器,在视图层进行数据取完毕后进行关闭session,这样就能够解决了NoSession异常了。可是怎么获取呢?这里又想到了前边学习的ThreadLocal,咱们能够将Session对象放到Threadlocal对象中,和线程进行绑定,到视图层再经过ThreadLocal进行获取关闭便可。
b,解决方案,AOP编程思想,想必都想到了Spring框架了吧,的确,Spring框架提供了OpenSessionInViewFilter过滤器解决NoSession异常,这里咱们只须要配置一下便可。在web.xml中进行此过滤器的配置便可:
<!-- 过滤器须要配置在Struts2框架过滤器前面,不然不起做用。 --> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping
c,配置的顺序wenti,应该将openSessionInViewFilter配置到Struts2的流程前边,这是由于Filter执行顺序是从上向下的,并且Struts2框架的执行流程基本上包含了整个项目顺序的所有流程,MVC流程框架么,就体如今这里了。配置到Struts2框架的流程后边的过滤器是起不到做用的。
这些是Hibernate框架中重要的知识,咱们能够经过合理使用缓存和lazy机制,使咱们的程序变得性能更增强,考虑优化项目时,这两项是必需要考虑的。这些东西看起来是比较虚的内容,还须要咱们经过一些小例子和实际应用加深理解。