`

十九 hibernate3之缓存

 
阅读更多
什么是缓存?现在我们来看一个模拟的缓存操作
模拟一个缓存例子

package cn.itcast.hibernate;

import java.util.HashMap;
import java.util.Map;

import cn.itcast.hibernate.domain.User;

public class CacheDemo {

	static Map cache = new HashMap();

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		User u = getUser(1);	
		
		User u1 = getUser(1);

	}

	public static void update(User user){
		updateDB(user);
		String key = User.class.getName() + user.getId();
		cache.remove(key);
	}
	
	

	public static User getUser(int id) {
		String key = User.class.getName() + id;
		User user = (User) cache.get(key);
		if (user != null)
			return user;
		user = getFromDB();
		cache.put(key, user);
		return user;
	}
	
	private static void updateDB(User user) {
		// TODO Auto-generated method stub
		
	}
	private static User getFromDB() {
		// TODO Auto-generated method stub
		return null;
	}
}

这里实现的是简单的模拟缓存原理,只是简单的把数据放入到Map集合中去
牵扯的数据有键值更新加入删除操作



缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、
删除缓存中的无效数据。
一级缓存,Session级共享。
save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都会将对象放在一级缓存中,
一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容。 

理解:Session级缓存是相当短暂的,一个请求的完成,Session就会关闭,一级缓存是由Session去控制的,如果Session关闭
缓存数据也随之不存在,下次访问数据,还是要去访问数据库

二级缓存

二级缓存,SessionFactory级共享。
实现为可插拔,通过修改cache.provider_class参数来改变;
	hibernate内置了对EhCache,OSCache,TreeCache,SwarmCache的支持,
	可以通过实现CacheProvider和Cache接口来加入Hibernate不支持的缓存实现。
在hibernate.cfg.xml中加入:
	<class-cache class="className" usage="read-only"/>
	或在映射文件的class元素加入子元素:
	<cache usage="read-write"/>
	其中usage:read-only,read-write,nonstrict-read-write,transactional
Session的:save(这个方法不适合native生成方式的主键),
	update,saveOrUpdate,list,iterator,get,load,以及Query,Criteria都会填充二级缓存,
	
	但只有(没打开查询缓存时)Session的iterator,get,load会从二级缓存中取数据(iterator可能存在N+1次查询)。
Query,Criteria(查询缓存)由于命中率较低,所以hibernate缺省是关闭;修改cache.use_query_cache为true打开对查询的缓存,
并且调用query.setCacheable(true)或criteria.setCacheable(true)。
SessionFactory中提供了evictXXX()方法用来清除缓存中的内容。
统计信息打开generate_statistics,用sessionFactory.getSatistics()获取统计信息。 


下面我们来看二级缓存的一些重要参数
##########################
### Second-level Cache ###
##########################

## optimize chache for minimal "puts" instead of minimal "gets" (good for clustered cache)

#hibernate.cache.use_minimal_puts true


## set a prefix for cache region names

hibernate.cache.region_prefix hibernate.test


## disable the second-level cache

#hibernate.cache.use_second_level_cache false


## enable the query cache

#hibernate.cache.use_query_cache true


## store the second-level cache entries in a more human-friendly format

#hibernate.cache.use_structured_entries true


## choose a cache implementation

#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider   
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider


## choose a custom query cache implementation

#hibernate.cache.query_cache_factory



解释: 
#hibernate.cache.use_second_level_cache false
这个是用来打开二级缓存的,一般在hibernate的hibernate.cfg.xml文件中去配置
配置方法:
1<property name="cache.use_second_level_cache">true</property>
这里只是配置二级缓存打开,缺省的就是true
2还要进一步配置,其二级缓存是用什么框架实现的
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider    
<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
并且需要把OSCache的配置文件加入到工程的src根目录下 oscache.properties 
同时需要引入OSCache框架包 oscache-2.1.jar
3还需要配置哪些类的对象需要二级缓存
<class-cache usage="read-only" class="vo.util.bean.Department"/>
usage节点是配置缓存策略 策略有四种
- read-only 只能对其读取用到,如果对所配置的类修改就报异常,效率比较高
- read-write  严格的读写限制
- nonstrict-read-write 
- transactional 事务型缓存

还有一种在映射文件中去配置缓存的对象 这相对一些比较简单 推荐方式
直接在映射文件中的class节点下加入 <cache usage="read-only"/> 
完整的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="vo.util.bean">

	<class name="Department">
	<!--是否使用SessionFactory缓存-->
	<cache usage="read-only"/>

		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<!-- 配置一对多的映射关系  -->
		<set name="ems" cascade="all">
		<!-- 关联关系的外键  -->
		<key column="depaer_id"/>
		   <!-- 关联关系的实体类配置 -->
		  <one-to-many  class="Employee" />
		</set>
	</class>
	
</hibernate-mapping>
4 OSCacheProvider提供者的配置文件 

使用统计来分析缓存是否数据的正确
 <!-- 统计数 -->
<property name="generate_statistics">true</property>


完整的hibernate的配置文件
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
	<property name="connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<property name="connection.url">jdbc:mysql:///test</property>
	<property name="connection.username">root</property>
	<property name="connection.password">root</property>
	<!-- 指定其方言 方言的作用就是告诉hibernate是哪种数据库 -->
	<property name="dialect">
		org.hibernate.dialect.MySQLDialect
	</property>
	<!-- 指定其hibernate是否根据映射文件自动创建表 -->
	<property name="hbm2ddl.auto">create</property>
	<property name="show_sql">true</property>
	<!-- 配置二级缓存是否打开 -->
	<property name="cache.use_second_level_cache">true</property>
	<!--二级缓存的提供者  这里需要注意的是你的工程中有没有OScache包 oscache-2.1.jar
	并且需要把oscache.properties文件拷贝进工程类路径的src目录下 在这个文件里配置
	cache.capacity参数
	-->
	<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>
	<!-- 这里配置哪些类的对象需要缓存 usage是缓存策略 -->
	<!--class-cache usage="read-only" class="vo.util.bean.Department"/-->
	
    <!-- 统计数 -->
    <property name="generate_statistics">true</property>
    
	<mapping resource="vo/util/bean/Department.hbm.xml" />
	<mapping resource="vo/util/bean/Employee.hbm.xml" />

</session-factory>
</hibernate-configuration>


然后就可以执行
Statistics st = HibernateUtil.getSessionFactory().getStatistics();
System.out.println("put:" + st.getSecondLevelCachePutCount());
System.out.println("hit:" + st.getSecondLevelCacheHitCount());
System.out.println("miss:" + st.getSecondLevelCacheMissCount());

通过执行这代码就可以知道二级缓存数据的读取成功与否
st.getSecondLevelCachePutCount() 放入缓存数据次数
st.getSecondLevelCacheHitCount() 读取缓存成功次数
st.getSecondLevelCacheMissCount() 读取缓存失败次数

分析 一般程序在第一次与数据库进行交互的时候,hibernate会从缓存中去找,首先从
一级缓存中去找,然后从二级缓存中去找,如果没有找到才去访问数据库,第一次运行时
缓存数据是没有的,所以二级缓存miss一次,同时它会put一次,第二次执行时,所以就会
报成功一次 

一级缓存数据的清理
  session=HibernateUtil.getSession();
 session.evict(arg0) 清理单个某一类Class的数据
session.clear() 清理全部一级缓存数据

二级缓存数据的清理
  HibernateUtil.getSessionFactory().evict(arg0) 清理单个缓存对象的数据
HibernateUtil.getSessionFactory().evict(arg0,id) 清理某一条单个缓存对象的某一条数据


二级缓存,SessionFactory级共享。
实现为可插拔,通过修改cache.provider_class参数来改变;
	hibernate内置了对EhCache,OSCache,TreeCache,SwarmCache的支持,
	可以通过实现CacheProvider和Cache接口来加入Hibernate不支持的缓存实现。
在hibernate.cfg.xml中加入:
	<class-cache class="className" usage="read-only"/>
	或在映射文件的class元素加入子元素:
	<cache usage="read-write"/>
	其中usage:read-only,read-write,nonstrict-read-write,transactional
Session的:save(这个方法不适合native生成方式的主键),
	update,saveOrUpdate,list,iterator,get,load,以及Query,Criteria都会填充二级缓存,
	但只有(没打开查询缓存时)Session的iterator,get,load会从二级缓存中取数据(iterator可能存在N+1次查询)。
Query,Criteria(查询缓存)由于命中率较低,所以hibernate缺省是关闭;修改cache.use_query_cache为true打开对查询的缓存
,并且调用query.setCacheable(true)或criteria.setCacheable(true)。
SessionFactory中提供了evictXXX()方法用来清除缓存中的内容。
统计信息打开generate_statistics,用sessionFactory.getSatistics()获取统计信息。 

e
分布式缓存
一个系统搭建多台服务器,一个数据库 并发访问共享出现问题

解决 中央缓存


使用缓存的条件
1.读取大于修改。
2.数据量不能超过内存容量。
3.对数据要有独享的控制。
4.可以容忍出现无效数据。


事务
	单个数据库(一个SesisonFactory对应一个数据库),由JDBC实现。
	Session session = null;
	Transaction tx =null;
	try {
		session = sessionFactory.openSession();
		tx = session.beginTransaction();
		//process
		tx.commit();
	} catch(HibernateException e){
		if(tx != null)tx.rollback();throw e;
	}finally {
		if (session != null)session.close();
	}
	connection.setAutoCommit(false);
	connection.commit();conn.rollback();



JTATransaction
	可以简单的理解成跨数据库的事物,由应用JTA 容器实现;
	使用JTATransaction需要配置hibernate.transaction.factory_class参数,
	该参数缺省值是org.hibernate.transaction. JDBCTransactionFactory,
	当使用JTATransaction时需要将该参数改成org.hibernate.transaction.JTATransactionFactory,
	并配置jta.UserTransaction参数JNDI名(Hibernate在启动JTATransaction时要用该值到JNDI的上
	下文Context中去找javax.transaction.UserTransaction)。
javax.transaction.UserTransactin tx = context.lookup(“jndiName”);
try{
	tx.begin();
	//多个数据库的session操作;
	//session1….
	//session2….
	tx.commit();
}catch(Exception e){
	tx.rollback(); throw e;
}



end 完毕!

 

分享到:
评论

相关推荐

    Hibernate二级缓存

    Hibernate二级缓存是一种提高应用程序性能的技术,它将数据存储在SessionFactory级别的缓存中,使得数据可以在不同的Session之间共享。这与一级缓存(Session级别)不同,一级缓存仅存在于单个Session生命周期内,当...

    hibernate一级缓存和二级缓存的区别与联系

    Hibernate 是一个流行的对象关系映射(ORM)框架,它提供了数据缓存机制以优化数据库访问性能。缓存机制分为一级缓存和二级缓存,两者都有助于减少对物理数据库的直接访问,从而提高应用程序的运行效率。 一级缓存...

    hibernate一级缓存、二级缓存和查询缓存

    **hibernate一级缓存、二级缓存和查询缓存** 在Java的持久化框架Hibernate中,缓存机制是提高应用程序性能的关键要素。缓存能够减少数据库的访问次数,提高数据读取速度,并且在一定程度上降低了系统的负载。本文将...

    hibernate二级缓存实例

    3. 配置实体类:在实体类上使用`@Cacheable`、`@Cache`等注解,声明该类及属性参与缓存。 4. 配置缓存策略:定义缓存区域,设置缓存策略(如过期时间、更新策略等)。 5. 应用到查询:对于查询结果,可以使用`...

    hibernate 二级缓存详解

    Hibernate 二级缓存是针对SessionFactory级别的全局缓存,与一级缓存(Session级别)不同,一级缓存只在单个Session生命周期内有效。二级缓存则允许不同Session之间共享数据,提高了数据访问效率,减少了对数据库的...

    Hibernate一级缓存、二级缓存以及查询缓存实例

    在Java的持久化框架Hibernate中,缓存机制是优化数据库操作性能的重要手段。本文将深入探讨Hibernate的一级缓存、二级缓存以及查询缓存,通过具体的实例来阐述它们的工作原理和使用方法。 首先,我们从一级缓存开始...

    hibernate二级缓存示例源码

    **hibernate二级缓存详解** Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,在处理大量数据时,性能优化显得尤为重要,这就是二级缓存的作用。本文将深入探讨Hibernate...

    Hibernate一级缓存和二级缓存

    描述中提到的链接可能是对Hibernate缓存机制的详细技术博客,但具体内容未给出。因此,我们将基于常规的Hibernate缓存知识进行解释。 **一、Hibernate一级缓存** 一级缓存是每个Hibernate Session内的缓存,它是一...

    Hibernate 二级缓存

    Hibernate 二级缓存

    hibernate二级缓存包

    3. **缓存区域**:在Ehcache中,数据被划分到不同的缓存区域,每个区域都有独立的配置,例如,我们可以为实体类创建特定的缓存区域,确保不同实体类的数据不相互混淆。 4. **缓存策略**:Ehcache支持多种缓存策略,...

    hibernate一级缓存

    在Java的持久化框架Hibernate中,一级缓存是其核心特性之一,它为提高数据库操作效率、减少对数据库的访问提供了重要支持。一级缓存,也称为session缓存,是每个Hibernate Session内部管理的一个内存结构。在本篇...

    hibernate二级缓存

    Hibernate 二级缓存是一种高效的数据存储机制,它能够显著提升Web应用的性能,尤其是在处理大量数据流动时。缓存的主要目标是减少应用与数据库之间的交互次数,从而降低延迟并减轻数据库服务器的压力。在Hibernate...

    hibernate二级缓存java包下载

    3. **实现二级缓存**: - 配置缓存插件:如 Ehcache、Infinispan 或 Hazelcast,这些插件需要添加到 Hibernate 的配置文件中,并指定对应的缓存提供商。 - 类和集合的缓存配置:在实体类上使用 `@Cacheable` 注解...

    Hibernate 二级缓存 总结整理

    3. **缓存策略(Cache Strategy)**:Hibernate提供了不同的缓存策略,包括读/写策略、只读策略和非事务性写入策略。读/写策略是最常用的,它在读取时从缓存中获取数据,更新时将数据写回数据库并同步到缓存;只读...

    Spring集成的Hibernate配置二级缓存

    3. **配置Spring整合Hibernate**:在Spring的配置文件(如applicationContext.xml)中,我们需要配置Hibernate SessionFactory,并指定缓存相关的bean。例如: ```xml ...

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

    本篇文章将深入探讨Hibernate的二级缓存机制,以及如何进行一级缓存与二级缓存的同步,同时还会介绍二级缓存的配置文件设置。 一级缓存是Hibernate默认提供的缓存,每个SessionFactory实例都有一个一级缓存。当对象...

    Hibernate二级缓存+分页功能

    3. 在实体类上添加`@Cacheable`或`@Cache`注解,声明哪些实体类或属性需要缓存。 4. 对于特定查询,可以使用`@CacheRegion`注解来定义查询结果的缓存区域。 二级缓存能有效减少对数据库的访问,提高性能,但需要...

    springboot+jpa(hibernate配置redis为二级缓存) springboot2.1.4

    3. **配置Hibernate二级缓存**: 在`application.yml`或`application.properties`中开启Hibernate二级缓存并指定使用Redis: ```yaml spring: jpa: hibernate: cache: use_second_level_cache: true region....

Global site tag (gtag.js) - Google Analytics