`
smiky
  • 浏览: 257798 次
  • 性别: Icon_minigender_1
  • 来自: 天门
社区版块
存档分类
最新评论

lazy及缓存(转)

阅读更多

转自:http://ronaldo97.blog.163.com/blog/static/122099105200971810469835/

lazy,延迟加载

Lazy的有效期:只有在session打开的时候才有效;session关闭后lazy就没效了。

lazy策略可以用在:

* <class>标签上:可以取值true/false

* <property>标签上,可以取值true/false,这个特性需要类增强

* <set>/<list>等集合上,可以取值为true/false/extra

* <one-to-one>/<many-to-one>等标签上,可以取值false/proxy/no-proxy

6.1 get和load的区别:

* get不支持延迟加载,而load支持。

* 当查询特定的数据库中不存在的数据时,get会返回null,而load则抛出异常。

6.2 类(Class)的延迟加载:

* 设置<class>标签中的lazy="true",或是保持默认(即不配置lazy属性)

* 如果lazy的属性值为true,那么在使用load方法加载数据时,只有确实用到数据的时候才会发出sql语句;这样有可能减少系统的开销。

* //不会发出查询sql

       System.out.println("group id=" + group.getId());

这里有一个问题,为什么加载主键的时候不需要发出sql语句。

6.3 集合(collection)的延迟加载:可以取值true,false,extra

* 保持集合上的lazy的默认值,此时的效果和lazy="extra"是基本一样的。

   * 设置集合上的lazy=extra,此时的效果和lazy属性的默认值是基本一样的。但是推荐使用这个属性值,因为在统计时这种情况显得比较智能。当然延迟是有效果的。

* 设置集合上的lazy=false

true:默认取值,它的意思是只有在调用这个集合获取里面的元素对象时,才发出查询语句,加载其集合元素的数据

false:取消懒加载特性,即在加载对象的同时,就发出第二条查询语句加载其关联集合的数据

extra:一种比较聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate

并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据

6.4 Hibernate单端关联懒加载策略:即在<one-to-one>/<many-to-one>标签上可以配置

懒加载策略。可以取值为:false/proxy/no-proxy

false:取消懒加载策略,即在加载对象的同时,发出查询语句,加载其关联对象

proxy:这是hibernate对单端关联的默认懒加载策略,即只有在调用到其关联对象的方法的时候才真正发出查询语句查询其对象数据,其关联对象是代理类

no-proxy:这种懒加载特性需要对类进行增强,使用no-proxy,其关联对象不是代理类

注意:在class标签上配置的lazy属性不会影响到关联对象!!!

 

 

 

转自:http://blog.csdn.net/defonds/archive/2008/04/20/2308972.aspx

缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。

  缓存的介质一般是内存,所以读写速度很快。但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。

  Hibernate的缓存包括Session的缓存和SessionFactory的缓存,其中SessionFactory的缓存又可以分为两类:内置缓存和外置缓存。Session的缓存是内置的,不能被卸载,也被称为Hibernate的第一级缓存。SessionFactory的内置缓存和Session的缓存在实现方式上比较相似,前者是SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集合属性包含的数据。SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句,映射元数据是映射文件中数据的拷贝,而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质可以是内存或者硬盘。SessionFactory的外置缓存也被称为Hibernate的第二级缓存。

  Hibernate的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝,那么它们之间的区别是什么呢?为了理解二者的区别,需要深入理解持久化层的缓存的两个特性:缓存的范围和缓存的并发访问策略。

  持久化层的缓存的范围

  缓存的范围决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类。

  1 事务范围:缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。在此范围下,缓存的介质是内存。事务可以是数据库事务或者应用事务,每个事务都有独自的缓存,缓存内的数据通常采用相互关联的的对象形式。

  2 进程范围:缓存被进程内的所有事务共享。这些事务有可能是并发访问缓存,因此必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期,进程结束时,缓存也就结束了生命周期。进程范围的缓存可能会存放大量的数据,所以存放的介质可以是内存或硬盘。缓存内的数据既可以是相互关联的对象形式也可以是对象的松散数据形式。松散的对象数据形式有点类似于对象的序列化数据,但是对象分解为松散的算法比对象序列化的算法要求更快。

  3 集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共享。缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致性,缓存中的数据通常采用对象的松散数据形式。

  对大多数应用来说,应该慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定会比直接访问数据库数据的速度快多少。

  持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有查到相应的数据,还可以到进程范围或集群范围的缓存内查询,如果还是没有查到,那么只有到数据库中查询。事务范围的缓存是持久化层的第一级缓存,通常它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常是可选的。

  持久化层的缓存的并发访问策略

  当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。

  在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。

  事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。

  读写型:提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。

  非严格读写型:不保证缓存与数据库中数据的一致性。如果存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。   只读型:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。

  事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低。

  什么样的数据适合存放到第二级缓存中?

  1、很少被修改的数据

  2、不是很重要的数据,允许出现偶尔并发的数据

  3、不会被并发访问的数据

  4、参考数据

  不适合存放到第二级缓存的数据?

  1、经常被修改的数据

  2、财务数据,绝对不允许出现并发

  3、与其他应用共享的数据。

  Hibernate的二级缓存

  如前所述,Hibernate提供了两级缓存,第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法比卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。

  第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。

  Hibernate的二级缓存策略的一般过程如下:

  1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。

  2) 把获得的所有数据对象根据ID放入到第二级缓存中。

  3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。

  4) 删除、更新、增加数据的时候,同时更新缓存。

  Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query缓存。

  Hibernate的Query缓存策略的过程如下:

  1) Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。

  2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。

  3) Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的Query Key都要从缓存中清空。

 

 

分享到:
评论

相关推荐

    hibernate 中的lazy属性祥解.txt

    #### 潜在问题及解决策略 尽管懒加载带来了很多好处,但它也有一定的局限性和潜在的问题。例如,如果在关闭了Session后尝试访问懒加载的属性,将会抛出异常,因为此时Hibernate已经无法重新建立数据库连接来加载...

    lazy-cache:惰性缓存,过期时异步自动重置缓存

    惰性缓存节点的惰性内存高速缓存,过期时异步自动重置高速缓存安装 npm i lazycache --save用法lazyCache() 使用工厂方法初始化缓存对象: var defaultCacheTime = 300000 ; // 300000 ms = 5 minvar cache = ...

    C#使用Lazy延迟加载

    7. **应用场景**:延迟加载常用于数据库连接、大型对象树、虚拟属性、缓存策略等场景。例如,在博客系统中,当用户查询一个博客时,我们可能并不需要立即加载所有相关文章,而是等到用户请求查看文章时再加载,这样...

    Lazy snapping code

    5. **性能优化**:为了实现高效地懒加载,开发者需要注意几个关键点:数据的分页处理、正确的缓存策略、适当的异步加载以及避免阻塞主线程。合理运用这些策略可以确保应用在加载大量数据时仍保持流畅。 6. **用户...

    Python库 | lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl

    3. **缓存策略**:当需要缓存某些结果,但只在首次访问时计算时,`lazy_object_proxy`是一个好选择。 `lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl`是一个针对Python 3.7的二进制包,适用于32位Windows系统。...

    npm_lazy:NPM的惰性本地缓存,以使您的本地部署更快

    npm_lazy在您的本地网络上缓存程序包,使事情更快,更可预测 如果100个服务器同时请求相同的程序包元数据,则npm_lazy确保(最多)仅一个请求发送到npm注册表。 没有要安装,复制或管理的数据库。 数据以JSON和tar...

    Python库 | lazy_object_proxy-1.4.2-cp37-cp37m-win_amd64.whl

    在缓存策略中,可以使用它实现按需加载缓存项,减少无效的内存占用。此外,它也可以用于构建复杂的依赖注入框架,或者优化那些需要大量实例化但使用频率不高的对象的代码。 总的来说,`lazy_object_proxy`库是...

    延时加载+静态资源本地缓存

    接下来,我们讨论图片资源的延时加载,也称为懒加载(Lazy Loading)。在传统的网页加载模式下,所有图片都会随着页面一起加载,这可能导致页面加载时间过长,特别是对于含有大量图片的页面。通过延迟加载,我们只在...

    当设置lazy=true时,怎样使用extjs和Hibernate

    - 考虑使用缓存策略,例如在客户端使用ExtJS的本地存储(localStorage)或在服务器端使用二级缓存(如Hibernate的EHCache)。 6. **源码分析**: - 分析`base_extjs_test1.jsp`源码,可以了解如何在实际代码中...

    mybatis3--延迟加载,缓存

    在 MyBatis 中,延迟加载(Lazy Loading)和缓存是两个非常重要的特性,它们对于提升应用程序性能和减少数据库访问有着显著作用。 **延迟加载(Lazy Loading)** 延迟加载是一种设计模式,它在对象被首次请求时才...

    Dagger中Inject、Lazy、Provider的理解

    `Lazy`会在首次调用`Lazy.get()`方法时计算依赖项,并将其缓存起来,之后的所有调用都将返回同一个缓存的对象。 ##### 示例:Lazy Injection (懒加载注入) ```java final class LazyCounter { @Inject Lazy...

    Hibernate缓存

    4. hibernate延迟加载.doc:这部分可能涵盖了Hibernate的懒加载(Lazy Loading)机制,这是第一级缓存的一种优化方式,只有在真正需要时才会加载关联的对象。 5. hibernate二级缓存攻略.docx:这份文档可能提供了一...

    Java框架篇—hibernate之缓存机制_.docx

    **三、延迟加载(Lazy Loading)与Session** 延迟加载是指在真正需要数据时才加载,而不是在对象初始化时。Hibernate通过绑定Session到ThreadLocal来保证在同一个请求中使用的Session是一致的,即使在HTTP请求结束...

    Mybatis延迟加载和缓存

    本篇将深入探讨 Mybatis 的两个重要特性:延迟加载(Lazy Loading)和缓存机制。 ### 延迟加载(Lazy Loading) 延迟加载是一种优化策略,它的核心思想是不立即加载所有数据,而是在实际需要时才进行加载。在 ...

    ListView分页加载及图片缓存显示的实现

    本示例“ListView分页加载及图片缓存显示的实现”着重讲解如何优化ListView的性能,提高用户体验,特别是处理大量图片时。以下是对该主题的详细解释: 1. **ListView分页加载**: 分页加载(Pagination)是一种...

    前端开源库-lazy-globby

    6. **性能优化**:在前端开发中,性能优化是重要的考虑因素,包括减少HTTP请求、压缩资源、缓存利用等,"lazy-globby" 就是为了优化 globbing 的性能。 7. **Node.js 和 NPM**:鉴于 "lazy-globby" 是前端库,很...

    Lazy Snapping

    【Lazy Snapping技术详解】 Lazy Snapping是一种优化技术,常用于图像处理和计算机图形学领域,特别是当处理大量数据或需要高效地更新视图时。它通过延迟计算或渲染某些部分,直到它们真正需要显示为止,以此提高...

    jQuery:图片缓存 10 jQuery Image Cache Plugins and Scripts

    **jQuery 图片缓存插件与脚本** 在网页设计中,图片的加载速度往往对用户体验有着重大影响。当用户浏览网页时,如果图片加载缓慢,可能会导致页面显得卡顿,影响用户对网站的整体评价。为了解决这个问题,开发者...

    iOS tableViewCell图片lazyload

    在iOS开发中,UITableView是展示数据的常用组件,特别是当数据包含大量图片时,为了提高应用性能和用户体验,通常会采用“图片懒加载”(lazyload)策略。懒加载是一种优化技术,它允许我们只在需要时加载资源,而...

Global site tag (gtag.js) - Google Analytics