`
里克尔奇
  • 浏览: 36215 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate的缓存策略

阅读更多

 

Hibernate 的一级缓存

是由 Session 提供的,因此它只存在于 Session 的生命周期中,当程序调用 save(),update(),saveOrUpdate() 等方法,及调用查询接口 list,filter,iterate 时,如 Session 缓存中不存在相应的对象, Hibernate 会把该对象加入到一级缓存中,当 Session 关闭时,该 Session 所管理的一级缓存也会立即被清除。

注意 :Hibernate 的一级缓存是 Session 所内置的,不能被卸载,也不能进行任何配置

一级缓存采用的是 key-value Map 方式来实现的,在缓存实体对象时,对象的主关键字 ID Map key ,实体对象就是对应的 value 。所以说,一级缓存是以实体对象为单位进行存储的,在访问时使用的是关键字 ID 。虽然, Hibernate 对一级缓存使用的是自动维护的功能,没有提供任何配置功能,但是可以通过 Session 中提供的方法来对一级缓存的管理进行手工干预。

使用 get 方法获得持久化对象时,首先查找 Session 缓存 ( 一级缓存 ) 是否有该对象,如果有,则获得该对象;如果没有,就会访问数据库,如果数据库中找不到数据,则返回 null
load
方法也是获得数据,但不同的地方是 load 方法已经假定数据库中一定存在该数据,如果在数据库中找不到该数据,则会抛出一个 org.hibernate.ObjectNotFoundException 异常。
load
方法获得对象的过程是: load 方法首先在 Session 缓存中查找对象,如果找不到则查找 SessionFactory 缓存 ( 二级缓存 ), 如果再找不到则访问数据库。值得注意的是, load 方法是假定数据库中一定有该数据,所以使用代理来延迟加载对象,只有在程序中使用了该对象的属性 ( 非主键属性 ) 时, Hibernate 才会进入 load 方法的获得对象过程。所以说,如果数据库中不存在该记录,异常是在程序访问该对象属性时抛出的,而不是在创建这个对象时就抛出。

Hibernate 中迭代( Iterate )查询实体对象 实现 à 1 、查询出我们需要的数据的所有 ID 1 条语句)。 2 、根据每个 ID 查询出每个对象( N 条语句)。

两次迭代( Iterate )查询实体对象 à 第二次迭代会发出查询 ID 的语句,然后 Hibernate 会查看缓存中是否有这些 ID ,如果有就不会再发 SQL 语句。

Hibernate 中迭代( Iterate )查询普通属性 实现 à 直接根据 ID 满足的条件,查询出所有的对象的属性(即属性集合)。

两次迭代( Iterate )查询普通属性 à 两次迭代都会根据 ID 满足的条件,查询出所有的对象的属性(即属性集合)。即不会缓存。

总结: Hibernate 的一级缓存只会对实体对像的查询进行缓存,不会对对象的普通属性进行缓存。

大批量的数据添加 à Hibernate 中添加很大量的数据是,默认会把所有添加的对象都缓存起来,这样有可能导致缓存的溢出,处理这种问题时可以确定多少条记录后显示的调用 flush ,并清理缓存。甚至直接使用 JDBC ,如果仍不能满足需求,可以使用数据库的工具,比如: Oracle SQL Loader

通过 Hibernate 的实现:

for(int i=0; i<10000000;i++){

Student student=new Student();

student.setName(“qq”+i);

session.save(student);

// 100 条更新一次

If(i%100==0){

session.flush()

// 清理缓存

session.clear();

}

}

session.getTransaction().commit();

 

Hibernate 的二级缓存

Hibernate 的二级缓存也称为进程级的缓存或是 sessionFactory 级的缓存,二级缓存可以被所有的 session 共享。二级缓存的生命周期和 sessionFactory 的生命周期是一样的,并且可以通过 sessionFactory 管理二级缓存。二级缓存是缓存实体对象的。缓存可以简单的看成一个 Map ,通过 key 在缓存里面找 value 无论 list load 还是 iterate ,只要读出一个对象,都会填充缓存。但是 list 不会使用缓存 ,而 iterate 会先取数据库 select id 出来,然后一个 id 一个 id load ,如果在缓存里面有,就从缓存取,没有的话就去数据库 load 。有说法说大型查询用 list 会把整个结果集装入内存,很慢,而 iterate select id 比较好,但是大型查询总是要分页查的,谁也不会真的把整个结果集装进来,假如一页 20 条的话, iterate 共需要执行 21 条语句, list 虽然选择若干字段,比 iterate 第一条 select id 语句慢一些,但只有一条语句,不装入整个结果集 hibernate 还会根据数据库方言做优化,比如使用 mysql limit ,整体看来应该还是 list 快。

二级缓存的实现 (EHCache) à 1 、在 Hibernate 包中的 etc 文件夹下拷贝 ehcache.xml src 下。这个文件的配置可以参考文件中的注释。 2 、在 hibernate.cfg.xml 文件中加入缓存的提供商

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>3 、启动二级缓存,

<property name="hibernate.cache.use_second_level_cache">true</property>4 、指定哪些实体需要使用二级缓存 à 可以在映射文件中采用 <cache> 标签指定(这个标签必须在 ID 标签之前)或者这 hibernate.cfg.xml 文件中统一指定

<class-cache class="com.bjpowernode.hibernate.Student" usage="read-only"/>

缓存使用的策略,通常采用 read-only (缓存在内存中是只读的不会改变)和 read-write (可读可写的)

二级缓存涉及到的一些情况:

* 开启二级缓存,在两个 session 中发 load (或 get )语句,第一个事务提交时肯定会发一条 SQL 语句,但是第二个 session 中不会发出 SQL 语句,因为不同的 session 会共享二级缓存中的数据。

*sessionFactory 管理二级缓存:

sessionFactory.evict(Cat.class, catId); // 清除指定ID 的实体

sessionFactory.evict(Cat.class);  // 清除所有实体

sessionFactory.evictCollection("Cat.kittens", catId); // 清除一个特定实// 体的集合

sessionFactory.evictCollection("Cat.kittens"); // 清除所有实体的集合

* 一级缓存和二级缓存的交互 à

可以通过 session.setCacheMode(CacheMode.IGNORE); 禁止将一级缓存中的数据放到二级缓存之中。如果另外一个session 进行同样的查询会发出SQL 语句。首先一级缓存失效,二级缓存中有没有放入数据,因此会发第二条语句。

例如:如果没有开启二级缓存,进行大批量更新时,通过没更新固定次数后显示调用flush() 和清除一级缓存,可以防止缓存溢出,但是开了二级缓存后,虽然通过以上步骤清除了一级缓存中的数据,但二级缓存中也放了一份数据,这样是无法避免内存溢出的。所以要通过 session.setCacheMode(CacheMode.IGNORE); 禁止将一级缓存中的数据放到二级缓存之中。

Hibernate 的查询缓存

* 缓存的对象 à 1 、普通属性的结果集2 、查询实体对象时会缓存实体对象的ID

* 缓存的声明周期 à 当管理的表发生修改时,查询缓存的生命周期结束。

* 查询缓存的配置 à hibernate.cfg.xml 文件中添加

<property name="hibernate.cache.use_query_cache">true</property>

开启查询缓存,默认为false

在程序中手动的启用 à query.setCacheable(true)

* 查询缓存的一些使用情况:1 、开启查询缓存,关闭二级缓存,采用了query.list() 查询普通的属性,无论在一个session 还是不同的session 中进行两次查询查询都只发出一条SQL 语句。查询缓存和session 的生命周期没有关系2 、开启查询缓存,关闭二级缓存,两个session 中发query.iterate() 查询,第二个session 会发出查询语句,query.iterate() 查询普通属性它不会使用查询缓存, 查询缓存只对query.list() 起作用 3 开启查询缓存,关闭二级缓存,采用query.list() 查询实体,两个session 中发query.list() 查询,第二个session 会发出NSQL 语句(这N 条语句是根据ID 进行查询实体),因为前面说过,查询实体对象时查询缓存会缓存实体对象的id ,第二次执行query.list(), 将查询缓存中的id 依次取出,分别到一级缓存和二级缓存中查询相应的实体对象,如果存在就使用缓存中的实体对象,否则根据id 发出查询学生的语句。如果开启二级缓存就不会发出N+1 条语句了

* 总结: 查询缓存通常会和二级缓存一起使用

 

1
0
分享到:
评论

相关推荐

    hibernate 缓存策略

    **hibernate缓存策略详解** Hibernate作为Java领域中广泛使用的ORM框架,其在处理大量数据时,为了提高性能和减少数据库的访问压力,引入了缓存机制。本文将深入探讨Hibernate的缓存策略,包括一级缓存、二级缓存...

    hibernate缓存策略

    ### Hibernate缓存策略详解 #### 一、理解Hibernate缓存 ##### 1.1 缓存概念 在软件开发领域,缓存技术是一项重要的优化手段,它可以显著提高应用程序的性能和响应速度。Hibernate作为一种持久层框架,其核心功能...

    Hibernate缓存策略

    Hibernate缓存原理及调优策略 Hibernate缓存原理调优策略

    Hibernate缓存策略(一级缓存、二级缓存).docx

    Hibernate 缓存策略是优化应用程序性能的关键组成部分,尤其是在频繁访问数据库的情况下。缓存可以减少对物理数据库的直接访问,提高响应速度。本文将详细介绍Hibernate的一级缓存和二级缓存。 一级缓存,也称为...

    Hibernate缓存

    6. hibernate缓存策略.pdf:这可能包含对Hibernate缓存的各种策略(如读写策略、只读策略等)的详细解析,以及如何根据业务需求选择合适的策略。 7. 高并发web架构.pdf:这可能涉及如何在高并发场景下设计和优化Web...

    深入理解Hibernate缓存

    ### 深入理解Hibernate缓存 #### 一、Hibernate缓存概述 Hibernate作为一款流行的Java持久层框架,为开发者提供了高效且灵活的数据访问能力。其中,缓存机制是Hibernate性能优化的重要组成部分之一。理解Hibernate...

    Hibernate 缓存 实例

    6. Hibernate缓存策略 在Hibernate3之后,官方开始推荐使用二级缓存,因为它的缓存效果更为显著。一级缓存虽然能提高单个Session的效率,但无法解决多线程环境下数据同步的问题。因此,合理地使用二级缓存能够有效地...

    Hibernate缓存技术研究

    ### Hibernate缓存技术研究 #### 一、引言 Hibernate是一种强大的对象-关系映射(Object-Relational Mapping,简称ORM)工具,主要用于Java环境下的应用程序。它能够将应用程序中的对象模型映射到关系型数据库的表...

    Hibernate缓存深入详解 from ITEye

    **Hibernate缓存深入详解** 在Java企业级应用开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,随着应用规模的扩大,数据访问性能成为了一个不可忽视的问题。这时,...

    hibernate二级缓存java包下载

    二级缓存是 Hibernate 缓存策略的一部分,它在应用程序的多个会话之间共享数据,进一步优化了数据库访问效率。 二级缓存分为以下关键知识点: 1. **一级缓存与二级缓存的区别**: - 一级缓存:每个 Hibernate ...

    hibernate缓存

    ### Hibernate缓存机制及优化策略 #### 一、概述 Hibernate作为一款优秀的对象关系映射(ORM)框架,在Java开发领域被广泛应用于数据库操作。它提供了丰富的缓存机制来提高应用性能并降低数据库访问压力。本文将...

    Hibernate缓存,性能优化

    综上所述,Hibernate缓存机制是提升应用性能的重要手段,通过合理配置缓存策略、优化查询方式、管理数据库连接以及实施有效的监控和调优措施,可以显著提高Hibernate应用的运行效率和用户体验。然而,缓存的使用并非...

    hibernate二级缓存jar包

    二级缓存是Hibernate缓存策略的重要组成部分,它允许我们在多个会话之间共享数据,从而提升应用程序的效率。 Ehcache是Hibernate常用的一种二级缓存实现,它是一个高性能、内存级的缓存解决方案。Ehcache提供了本地...

    Hibernate缓存详解

    **Hibernate缓存详解** 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。为了提高数据访问性能,Hibernate引入了缓存机制,它可以减少对数据库的直接访问,从而提升应用的...

    hibernate面试题2

    3. **Hibernate缓存策略**: - **只读(Read-only)**:适用于不更新的数据,是最简单且高效的策略。 - **读/写(Read/write)**:适用于需要更新的数据,比只读策略消耗更多资源。 - **非严格读/写(Nonstrict ...

    hibernate缓存机制

    Hibernate缓存机制是提高应用程序性能的关键技术之一,它通过存储数据副本减少对物理数据库的访问。缓存可以分为两层:第一级缓存和第二级缓存。 **第一级缓存**是内置在Session中的,它是不可卸载的,也称为...

    Hibernate缓存与spring事务详解

    **标题:“Hibernate缓存与Spring事务详解”** 在IT领域,尤其是Java开发中,Hibernate作为一款流行的ORM(对象...在实际项目中,需要根据业务需求和场景选择合适的缓存策略和事务处理方式,以达到最佳的开发效果。

Global site tag (gtag.js) - Google Analytics