`
里克尔奇
  • 浏览: 35592 次
  • 性别: 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缓存原理调优策略

    hibernate缓存策略

    讲述如何设置和使用hibernate缓存

    hibernate 缓存策略

    NULL 博文链接:https://wangrusheng5200.iteye.com/blog/898231

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

    Hibernate是一个持久化框架,经常需要访问数据库。如果我们能够降低应用程序对物理数据库访问的频次,那会提供应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序运行时先从缓存中读写数据。

    Hibernate缓存技术研究

    Hibernate是一种面向Java环境的ORM工具。系统地分析了Hibernate的缓存结构,并描述了二级缓存的查询过程、缓存策略;同时总结了二级缓存使用中的一些限制,以及使用二级缓存的优化策略。

    hibernate缓存

    hibernate的缓存机制以及优化策略

    Hibernate缓存管理.doc

    Hibernate缓存管理,全面,易懂...

    hibernate 3中的缓存小结

     Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query Cache。 2.3.2. 什么样的数据适合存放到第二级缓存中? 1 很少被修改的数据 2 不是很...

    day37 05-HIbernate二级缓存:一级缓存更新同步到二级缓存及二级缓存配置文件

    NULL 博文链接:https://364232252.iteye.com/blog/2369161

    Hibernate框架 jar 架包 开发详解

    Hibernate 简介 Hibernate 开发流程 Hibernate 配置文件 Hibernate 核心接口和类 Hibernate ORM映射 HQL Hibernate 懒加载机制与抓取策略 Hibernate 缓存 Hibernate 锁机制

    彻底解决hibernate常见难点.zip

    Hibernate处理1-N关系时保存技巧、Hibernate缓存机制、Hibernate批量处理数据、Hibernate三种继承映射策略、hibernate映射体系、Hibernate主键生成策略、持久层DAO设计建议、基于xml文件的bean、使用HibernateAPI在...

    Hibernate学习笔记

    001 Hibernate 简介(开源 O/R 映射框架) 002 第一个 Hibernate 示例 003 hibernate 主要接口介绍 004 持久对象的生命周期介绍 005 query 接口初步 ...028 hibernate 缓存(性能优化策略) 029 hibernate 抓取策略

    Hibernate缓存管理

    doc格式。当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。在进程范围或集群范围的缓存...因此可以设定四种类型的并发访问策略,每一种策略对应一种事务隔离级别。

    hibernate基础教程

    Hibernate中的缓存 Hibernate中使用了一级缓存和二级缓存的机制来提高程序的性能. 一 为什么要使用缓存? 缓存是一块存储区域,可能是一块内存,也可能是一块硬盘.缓存...

    08.拓薪教育-hibernate4.3的hibernate.cfg.xml基本配置.part2

    高级Hibernate4开发技术:ORM思想,hibernate介绍,hibernate.cfg.xml配置,hbm.xml映射文件详解,主键生成策略使用,PO对象状态及状态的转换分析、一级缓存,Hibernate数据检索技术,Hibernate高级映射技术,...

    Hibernate+中文文档

    19.1. 缓存策略提供商(Cache Providers) 19.2. 各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support) 20.1. Summary 20.2. SchemaExport命令行选项 20.3. SchemaExport 连接属性 ...

    hibernate3.2中文文档(chm格式)

    19.1. 缓存策略提供商(Cache Providers) 19.2. 各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support) 20.1. Summary 20.2. SchemaExport命令行选项 20.3. SchemaExport 连接属性 ...

Global site tag (gtag.js) - Google Analytics