Hibernate缓冲策略 一

一、hibernate为什么提供缓存?

什么是缓存?

在内存里开辟一块空间把本来应该存在硬盘里面的数据,存在这个空间里面,将来,需要这块数据的时候直接在内存中获取。这个就可以简单理解为缓存。

Hibernate 是一个持久层框架,经常访问物理数据库,为了减低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能。

缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件,将同步缓存和物理数据源的数据。

那么,接下来,让我们来看看Hibernate的缓存原理是什么。

二、Hibernate 的缓存

首先,Hibernate的缓冲分两个级别:一级缓存 和 二级缓存。Hibernate一级缓存又称为 Session级别的缓存 ; 二级缓存又称为“SessionFactory的缓存”。由session ,和SessionFactory 中就可以看出,缓冲的作用范围不同。看两者的使用。

1、一级缓冲

Hibernate一级缓存又称为 Session级别的缓存 。Session的缓存是事务范围的缓存,所以一级缓冲的生命周期和session的生命周期是同步的。Session对象的生命周期通常对应一个数据库事务或者一个应用事务。在一级缓存中,持久化类的每个实例都具有唯一的OID。

在同一个session中,我们两次使用load来加载同一个对象,来看一级缓存:

@Test
 publicvoid cache1Test(){
       Session s=sessionFactory.openSession();
       s.beginTransaction();
       Person person=(Person)s.load(Person.class, 1);
       System.out.println(person.getName());
       //因为Session存在缓冲,所以第二次查询直接在session中取
       Person person2=(Person)s.load(Person.class, 1);
       System.out.println(person2.getName());
       s.getTransaction().commit();
    }

结果是只发出一条SQL语句,是第一个查询的sql语句,第二次查询直接使用的session缓冲中的数据对象。

这就是一级缓冲,只能用在同一个session中,不能跨session来取值,那要是需要跨session取值,怎么办呢?

对了,就是sessionFactory级别的缓冲,就像是sessionFactory管理所有的session一样,这里的二级缓冲就跳出来session的小圈子,可以供所有的session来取值。

2、二级缓存。

二级缓存又称为“SessionFactory的缓存”。是SessionFactory级别的缓冲,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。

二级缓存是可选的,是一个可配置的第三方插件,默认下SessionFactory不会启用这个插件,如果我们需要使用二级缓冲,就事先需要开启。

第一、开启缓存

我们需要在我们的hibernate.cfg.xml中开启我们的二级缓冲,如下:

<!-- 开启缓冲 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--指定是哪个二级缓冲-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 使用查询二级缓冲 -->
<propertyname="hibernate.cache.use_query_cache">true</property>

第二:指明那个实体类需要使用缓冲

我们需要指明那个实体类需要使用缓冲,这里有两种配置,一种是xml配置,一种是Annotation的配置,分别如下:

Annotation的配置如下:

@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
@Table(name="p_person")
public class Persion{

}

Xml的配置也有两种,一种是在各自的hbm文件配置,一种是在cfg中配置,

hbm文件的配置如下:

<class name="Person" table="t_person">
        <cache usage="read-write"/>
        <id name="id">
        ……
</class>

cfg文件的配置如下:

<!-- 指定Student使用二级缓存     -->
<class-cache class="com.hibernate.Persion" usage="read-only"/>

第三:需要提供第三方的cache。

其实二级缓冲并不是由Hibernate来提供,是由第三方提供的缓冲插件,通常有以下几种第三方缓冲插件:

  • EhCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
  • OSCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
  • SwarmCache:可作为集群范围内的缓存,但不支持Hibernate的查询缓存。
  • JBossCache:可作为集群范围内的缓存,支持事务型并发访问策略,对Hibernate的查询缓存提供了支持。

默认hibernate使用的是ehcache。默认的配置如下:

<defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

到这里配置结束,我们来进行测试。

 @Test
    publicvoid findTesterjihuanchong(){
        Sessions=sessionFactory.openSession();
        s.beginTransaction();
        Personperson=(Person)s.load(Person.class, 1);
        System.out.println(person.getName());
        s.getTransaction().commit();
        s.close();
        // 另起一个session
        Sessions2=sessionFactory.openSession();
        s2.beginTransaction();
        // 不会发SQL语句,读取的是二级缓存中的数据
        Personperson2=(Person)s2.load(Person.class, 1);
        System.out.println(person2.getName());
        s2.getTransaction().commit();
        s2.close();
    }

结果是:只有第一个session中发送了一条SQL语句,第二个session中没有发送。

以上是Hibernate的 一级缓存和二级缓存的介绍,其实 Hiberante还有第三种缓存:查询缓存。什么是查询缓存?查询缓冲和一级,二级缓存的区别是什么,将在下篇博客中说明。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-27 15:19:30

Hibernate缓冲策略 一的相关文章

Hibernate检索策略之延迟加载和立即加载

延迟加载:延迟加载(lazy load懒加载)是当在真正需要数据时,才执行SQL语句进行查询.避免了无谓的性能开销. 延迟加载分类:  1.类级别的查询策略 2.一对多和多对多关联的查询策略 3.多对一关联的查询策略 什么情况下使用延迟加载? 如果程序加载一个对象的目的是为了访问它的属性,可以采用立即加载.如果程序加载一个持久化对象的目的是仅仅为了获得它的引用,可以采用延迟加载. 如何配置延时加载? 在Hibernate中通过对.hbm的lazy属性来赋值,不同位置出现lazy的作用和取值也是不

Hibernate —— 检索策略

一.Hibernate 的检索策略本质上是为了优化 Hibernate 性能. 二.Hibernate 检索策略包括类级别的检索策略.和关联级别的检索策略(<set> 元素) 三.类级别的检索策略 1. 立即检索.延迟检索 2. 通过 <class> 节点的 lazy 属性来控制.默认为 true,即为延迟检索. 3. 只针对 session 的 load() 方法生效. 默认情况下,通过 load() 方法获取到的对象是一个代理对象,Hibernate 创建代理对象时,仅会初始化

三大框架 之 Hibernate生成策略与缓存策略(主键生成策略、持久化、持久化类划分、一级缓存、事物管理)

目录 Hibernate生成策略与缓存策略 主键生成策略 主键分类 主键的生成策略 持久化 什么是持久化 什么是持久化类 持久化类编写规则 持久化类的划分 三种状态区分 持久态对象特征 一级缓存 什么是缓存 一级缓存 一级缓存特点 一级缓存内部结构 事务管理 什么是事务 事务特性 事务的隔离级别 Hibernate设置事务的隔离级别 事务业务层连接 Hibernate生成策略与缓存策略 主键生成策略 主键分类 自然主键 主键本身就是表中的一个字段 实体中一个具体的属性,对象本身唯一的特性 创建一

hibernate(八) Hibernate检索策略(类级别,关联级别,批量检索)详解

序言 很多看起来很难的东西其实并不难,关键是看自己是否花费了时间和精力去看,如果一个东西你能看得懂,同样的,别人也能看得懂,体现不出和别人的差距,所以当你觉得自己看了很多书或者学了很多东西的时候,你要想想,你花费的也就那么一点时间,别人花你这么多时间也能够学到你所学到的东西,所以还是要继续努力.既然不是天才,唯有靠勤奋来弥补. --WH 一.概述 检索策略分三大块,类级别检索策略和关联级别检测策略. 类级别检索策略:get.load. 关联级别检索策略:order.getCustomer().g

Hibernate 检索策略

概述 检索数据时的 2 个问题: –不浪费内存:当 Hibernate 从数据库中加载 Customer 对象时, 如果同时加载所有关联的 Order 对象, 而程序实际上仅仅需要访问 Customer 对象, 那么这些关联的 Order 对象就白白浪费了许多内存. –更高的查询效率:发送尽可能少的 SQL 语句 类级别的检索策略 •类级别可选的检索策略包括立即检索和延迟检索, 默认为延迟检索 –立即检索: 立即加载检索方法指定的对象 –延迟检索: 延迟加载检索方法指定的对象.在使用具体的属性时

对Hibernate缓存策略的理解和应用

引自:http://www.blogjava.net/frostwood/archive/2010/01/06/308465.html Hibernate提供了三个级别的缓存策略:Session缓存(基本的事务级缓存),Query Cache(查询缓存),Seond-Level Cache(二级缓存) Session缓存(First-Level Cache):Session是Hibernate用于管理持久化对象的核心机制,它是针对持久性数据的事务级缓存.PersistenceContext中包括

Hibernate检索策略

Hibernate的检索策略主要分为两类: 1. 立即查询:根据id查询,调用get方法,调用get方法马上发送语句查询数据库 2. 延迟查询:根据id查询,还有load方法,调用load方法不会马上发送语句查询数据,只有得到对象里面的值的时候才会发送语句查询数据库. Hibernate的延迟查询又分为两类: 1. 类级别延迟:根据id查询返回实体类对象,调用load方法不会马上发送语句 2. 关联级别延迟:查询某个客户,在查询这个客户的所有联系人,查询客户的所有联系人的过程是否需要延迟,这个过

Hibernate检索策略与检索方式

hibernate的Session在加载Java对象时,一般都会把鱼这个对象相关联的其他Java对象也都加载到缓存中,以方便程序的调用.但很多情况下,我们不需要加载太多无用的对象到缓存中,一来会占用大量的内存,二来会增加数据库的访问次数,使得程序的运行效率降低.为了合理的使用缓存,Hibernate提供了不同的检索策略来解决这些问题. 作用域 在说检索策略之前,先了解一下检索策略的作用域,它分为:类级别和关联级别.类级别的作用域在检索数据时,检索的数据只包含一个类对象,不涉及与该类关联的其他对象

Hibernate命名策略

hibernate的命名策略,可以减少对数据库标识符命名的维护,进一步减少这部份命名的重复性代码量,以提高维护. hibernate的命名方式,有两类,一类是显式命名,一类是隐式命名. 显式命名:在映射配置时,设置的数据库表名,列名等,就是进行显式命名. 隐式命名:显式命名一般不是必要的,所以可以选择当不设置名称,这时就交由hibernate进行隐式命名,另外隐式命名还包括那些不能进行显式命名的数据库标识符.接口ImplicitNamingStrategy,就是用于实现隐式命名. 过滤命名:接口