`

10-Hibernate3.6.2 缓存

阅读更多

 对于Hibernate深层次的运用,缓存是必不可少的。因为利用缓存,可以提高Hibernate的性能。使用缓存涉及到三个操作:把数据放入缓存、从缓存中取数据、删除缓存中的无效数据。

 

一、一级缓存

一级缓存是Session级共享的,对于一级缓存而言,所有经过Session操作的实体,不管是使用save()update()或者saveOrUpdate()保存一个对象,还是使用load()get()list()iterate()scroll()方法获得一个对象时,该对象都将放入一级缓存中。

session = HibernateUtil.getSession();  
	Users users = (Users) session.get(Users.class, id);  
	System.out.println(users.getBirthday());  
	Users users2 = (Users) session.get(Users.class, id);  
	System.out.println(users.getName());  

该程序当第一次查询Users对象时,hibernate会先到一级缓存中查找缓存中是否有该实体,如果有,就直接拿,否则就到数据库中去读取。这里缓存中没有,所以hibernate会到数据库中去读取数据。这里产生一条SQL语句。同时hibernate会将该实体对象放入到一级缓存中去。当第二次还查询该实体对象的时候,hibernate同样会先到一级缓存中去读,结果一级缓存中存在该实体对象,所以直接拿。故上面的程序实例只会产生一条SQL语句。

Session调用flush()方法或者close()方法之前,这些对象都会一直缓存在一级缓存中。由于一级缓存不能控制缓存的对象数据,所以在大批量操作数据的时候可能会造成内存溢出。

清除缓存有两个方法:evil()clear()。其中evil()用于清除一条记录,它接受一个持久化类参数。Clear用于清除session里面所有的记录。

 

二、二级缓存

SessionFactory级别的二级缓存是全局的,应用的所有Session都共享这个二级缓存。但是二级缓存默认是关闭的,必须由程序显示开启

使用二级缓存一般有如下步骤:

          酷1、在hibernate.cfg.xml中开启二级缓存

		<property name="cache.use_second_level_cache">true</property>  

        酷2、设置二级缓存的实现类

    实际应用中一般不需要我们自己实现缓存,直接使用第三方提供的缓存即可。

<property name="cache.provider_class">org.hibernate.cache.EHCacheProvider
</property>  

 Hibernate3所支持的缓存实现(具体可以看官方文档):

 

          酷3、复制二级缓存的JAR包。

    使用第三方提供的缓存就必须将相应的JAR包复制到应用的类加载路径中去。这里我采用的是EHCache

    注意在使用EHCache的时候,要将入下两个JAR包也要加载到项目应用中:commons-logginbackport-util-concurrent

           酷4、将缓存实现所需要的配置文件添加到系统的类加载路径中。对于EHCache缓存而言,它需要一个ehcache.xml配置文件。配置文件代码如下:

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

           酷5、设置对那些实体类。实体的那些集合属性开启二级缓存。在这里一般有如下两种方法:

            1)、修改要使用缓存的映射文件。在持久化映射文件的<class.../>元素、或者<set.../><list.../>等集合元素内使用<cache.../>元素指定缓存策略

<hibernate-mapping package="com.hibernate.domain">
	<class name="Users">
		<cache usage="read-only"/>    <!-- 缓存策略为只读 -->
		<id name="id">
			<generator class="native" />
		</id>
		<property name="birthday" />
		
		<!-- 映射组件元素 -->
		<component name="name">
			<!-- 映射组件的name属性指向包含实体 -->
			<property name="firstName" column="first_name"/>
			<property name="lastName" column="last_name"/>
		</component>
	</class>
</hibernate-mapping>

              2)、在hibernate.cfg.xml文件中使用<class-cache.../>或者<collection-cache.../>元素对知道那个的持久化类、集合属性启用二级缓存

<class-cache usage="read-only" class="com.hibernate.domain.Users"/>

 

        酷6、测试

public void query(int id){
		Session session = null;
		try {
			session = HibernateUtil.getSession();
			Users users = (Users) session.get(Users.class, id);
			System.out.println(users.getBirthday());
		} finally{
			if(session!=null)
			  session.close();
		}
		
		try {
			session = HibernateUtil.getSession();
			Users users = (Users) session.get(Users.class, id);
			System.out.println(users.getName());
		}finally{
			if(session!=null)
			  session.close();
		}
	}

 当第一次查询Users实体之后,SessionFactory会将该实体缓存在二级缓存中,在这里先关闭session1然后重新创建session,在一次查询Users实体时,程序就可以直接使用缓存中已经存在的Users实体了。这里只产生一条SQL查询语句。

 

1、缓存策略

          二级缓存存在如下四种缓存策略:read-onlyread-writenonstrict-read-writetransaction

          1read-only:只读策略。如果应用程序只需要读取持久化实体的对象,无须对其进行修改,那么就可以对其设置为"只读"缓存策略。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。

               2read-write:读/写策略:如果应用程序需要更新数据,那么使用读/写缓存比较合适。如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。

            3nonstrict-read-write:非严格读/写策略。如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存策略。

            4transaction:事物缓存。Hibernate的事务缓存策略提供了全事务的缓存支持。这样的缓存只能用于JTA环境中,你必须指定为其hibernate.transaction.manager_lookup_class属性。

这里多说一点的是没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。

 

2、管理缓存

对于二级缓存而言,SessionFactory提供了许多方法用于清除缓存中实例、整个类、集合实例或者整个集合。

sessionFactory.evict(Users.class, id); //清除指定id的Users对象
sessionFactory.evict(Users.class); // 清除所有的Users对象
sessionFactory.evictCollection("Users.name",id); //清除指定id的Users所关联集合属性
sessionFactory.evictCollection("Users.name"); //清除所有Users所关联集合属性

 

SessionFactory还提供了一个getCache()方法,该方法返回一个Cache对象,通过该对象即可操作二级缓存中的实体、集合等。

CacheMode参数用于控制具体的Session如何与二级缓存进行交互。

            吐舌头 CacheMode.NORMAL - 从二级缓存中读、写数据。

            吐舌头CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。

            吐舌头CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。

          吐舌头CacheMode.REFRESH - 仅向二级缓存写数据,但不从二级缓存中读数据。通过 hibernate.cache.use_minimal_puts的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。

 

    如果需要查看二级缓存或查询缓存区域的内容,可以使用Hibernate的统计(Statistics API

为了开启二级缓存的统计功能,需要在hibernate.cfg.xml文件中进行配置。

<property name="generate_statistics">true</property>
<property name="cache.use_structured_entries">true</property>

 

  可以通过如下方式查看二级缓存的内容

Map cacheEntries = HibernateUtil.getSessionFactory().getStatistics()
    	.getSecondLevelCacheStatistics("com.hibernate.domain.Users").getEntries();
	System.out.println(cacheEntries);

 

3、查询缓存

一级、二级缓存都是对整个实体进行缓存,它不会缓存普通属性,如果想对普通属性进行缓存,则可以使用查询缓存。

使用查询缓存时,不仅需要所使用的HQL语句、SQL语句相同,还要求所传入的参数也相同。

要使用查询缓存就需要在hibernate.cfg.xml中开启查询缓存:

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

 

设置将会创建两个缓存区域 - 一个用于保存查询结果集;另一个则用于保存最近查询的一系列表的时间戳。

如若需要进行缓存,请调用 Query.setCacheable(true)方法,该方法用于开启查询缓存。这个调用会让查询在执行过程中时先从缓存中查找结果,并将自己的结果集放到缓存中去。

        如果你要对查询缓存的失效政策进行精确的控制,你必须调用Query.setCacheRegion()方法,为每个查询指定其命名的缓存区域。

	public void cacheQuery(){
		Session  session = HibernateUtil.getSession();
		List list = session.createQuery("from User u where u.id=:id")
		            .setInteger("id", 2)
		            .setCacheable(true)
		            .setCacheRegion("name")
		            .list();
	}

 

PS

         这部分更重要的实际项目中的运用!

 

 

 

 

  • 大小: 31.6 KB
分享到:
评论

相关推荐

    hibernate-distribution-3.6.2 API及jar包

    《Hibernate 3.6.2 API及jar包详解》 Hibernate,作为一个强大的对象关系映射(ORM)框架,是Java开发中的重要工具。本资源集合包含`hibernate-distribution-3.6.2`版本的API中文文档以及相关的jar包,旨在帮助...

    hibernate-distribution-3.6.2.Final-dist

    《Hibernate 3.6.2.Final:持久化框架的深度探索》 Hibernate,作为Java领域最著名的对象关系映射(ORM)框架之一,自诞生以来就备受开发者喜爱。本次我们关注的是其3.6.2.Final版本的源码包——`hibernate-...

    hibernate-distribution-3.6.2.Final-dist jar包

    10. **实体关系(Association)**:Hibernate支持多种关联映射,如一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)和多对多(ManyToMany),通过注解来定义这些关系。 11. **继承映射(Inheritance ...

    Hibernate Core 3.3.2.GA API (html官方英文版)

    Hibernate支持二级缓存,一级缓存在SessionFactory级别,二级缓存在应用级别。缓存能显著提高数据访问速度,Ehcache是常用的二级缓存提供者。 7. **Association(关联)** Hibernate支持一对一、一对多、多对一和...

    hibernate3.2+mysql+log4j

    2. **配置Hibernate**:编写hibernate.cfg.xml配置文件,指定数据库连接信息、方言、缓存策略等。 3. **映射对象**:创建实体类并使用注解或XML文件定义其与数据库表的映射关系。 4. **配置log4j**:根据需求调整log...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     22.4 管理Hibernate的第二级缓存  22.4.1 配置进程范围内的第二级缓存  22.4.2 配置集群范围内的第二级缓存  22.4.3 在应用程序中管理第二级缓存  22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的...

    spring4.2+hibernate4.2+struts2.3.29整合所需jar包

    `hibernate-core-4.1.9.Final.jar` 是Hibernate的核心库,包含了对SQL查询、实体管理和缓存等功能的实现。 3. **Struts 2**:Struts 2 是一个基于MVC(模型-视图-控制器)架构的Java Web应用框架,用于简化动态网站...

    jeesite lib2包

    Hibernate提供事务管理、缓存机制和强大的查询语言HQL,是Java领域中广泛使用的持久层框架。 2. **org.insightech.er_1.0.0.v20121127-2328.jar**:这是ER图设计工具Insight-ER的一部分,用于设计和管理数据库的...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    3.6.2 创建helloapp应用的目录结构 72 3.6.3 把helloapp应用作为独立应用程序运行 73 3.6.4 把helloapp应用作为Java Web应用运行 77 3.7 小结 78 3.8 思考题 80 第4章 hbm2java和hbm2ddl工具 83 本章介绍...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     22.4 管理Hibernate的第二级缓存  22.4.1 配置进程范围内的第二级缓存  22.4.2 配置集群范围内的第二级缓存  22.4.3 在应用程序中管理第二级缓存  22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     22.4 管理Hibernate的第二级缓存  22.4.1 配置进程范围内的第二级缓存  22.4.2 配置集群范围内的第二级缓存  22.4.3 在应用程序中管理第二级缓存  22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     22.4 管理Hibernate的第二级缓存  22.4.1 配置进程范围内的第二级缓存  22.4.2 配置集群范围内的第二级缓存  22.4.3 在应用程序中管理第二级缓存  22.4.4 Session与第二级缓存的交互模式  22.5 运行本章的...

    精通Hibernate:对象持久化技术第二版part3

    3.6.2 创建helloapp应用的目录结构 72 3.6.3 把helloapp应用作为独立应用程序运行 73 3.6.4 把helloapp应用作为Java Web应用运行 77 3.7 小结 78 3.8 思考题 80 第4章 hbm2java和hbm2ddl工具 83 本章介绍...

    Struts2.3.8整合Hibernate4.2,Spring3.2lucene 3 6 2 SSH整合1.0版

    Struts2.3.8、Hibernate4.2和Spring3.2是Java开发中的三大主流框架,它们分别负责Web层、持久层和业务层的管理,而Lucene 3.6.2则是一个强大的全文搜索引擎库。这个整合版本称为SSH整合1.0版,旨在提供一个高效、...

    Spring in Action(第2版)中文版

    3.6.2脚本化bean 3.6.3注入脚本化bean的属性 3.6.4刷新脚本化bean 3.6.5编写内嵌的脚本化bean 3.7小结 第4章通知bean 4.1aop简介 4.1.1定义aop术语 4.1.2spring对aop的支持 4.2创建典型的spring切面 4.2.1...

    Spring in Action(第二版 中文高清版).part2

    3.6.2 脚本化Bean 3.6.3 注入脚本化Bean的属性 3.6.4 刷新脚本化Bean 3.6.5 编写内嵌的脚本化Bean 3.7 小结 第4章 通知Bean 4.1 AOP简介 4.1.1 定义AOP术语 4.1.2 Spring对AOP的支持 4.2 创建典型的...

    Spring in Action(第二版 中文高清版).part1

    3.6.2 脚本化Bean 3.6.3 注入脚本化Bean的属性 3.6.4 刷新脚本化Bean 3.6.5 编写内嵌的脚本化Bean 3.7 小结 第4章 通知Bean 4.1 AOP简介 4.1.1 定义AOP术语 4.1.2 Spring对AOP的支持 4.2 创建典型的...

    iBATIS实战

    11.1.1 Hibernate版本的DAO实现 194 11.1.2 JDBC版本的DAO实现 199 11.2 为其他数据源使用DAO模式 203 11.2.1 示例:为LDAP使用DAO 203 11.2.2 示例:为Web服务使用DAO 208 11.3 使用Spring DAO 209 11.3.1 编写代码...

Global site tag (gtag.js) - Google Analytics