Hibernate之二级缓存

一,概述

1)Hibernate提供的缓存: 有一级缓存、二级缓存. 目的是为了减少对数据库的访问次数,提升程序执行效率!
2)一级缓存:基于Session的缓存,缓存内容只在当前session有效,session关闭,缓存内容失效!
特点:作用范围较小! 缓存的时间断, 缓存效果不明显!

3)二级缓存: Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据.这个缓存也叫二级缓存!
Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可;不想用,直接移除,不影响代码.
如果用户觉得hibernate提供的框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以.

二,Hibernate二级缓存

1)查看hibernate.properties文件,看看二级缓存怎样配置

##########################
### Second-level Cache ###
##########################

#hibernate.cache.use_second_level_cache false    --二级缓存默认不开启,需要手动开启
#hibernate.cache.use_query_cache 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

2)二级缓存,使用步骤

a) 开启二级缓存
b)指定缓存框架
c)指定那些类加入二级缓存
d)测试二级缓存!

3)配置

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<!-- 通常,一个session-factory节点代表一个数据库 -->
	<session-factory>
	
		<!-- 1. 数据库连接配置 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql:///hib_demo</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">abc</property>
		<!-- 
			数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
		 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
		
		<!-- 2. 其他相关配置 -->
		<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 2.2 格式化sql
		<property name="hibernate.format_sql">true</property>  -->
		<!-- 2.3 自动建表  -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		
		<!-- *********连接池配置*********** -->
		<!-- 配置连接池驱动管理类 -->
		<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
		<!-- 配置连接池参数信息 -->
		<property name="hibernate.c3p0.max_size">5</property>	<!-- 最大连接数 -->
		<property name="hibernate.c3p0.min_size">2</property>	<!-- 最小连接数 -->
		<property name="hibernate.c3p0.timeout">5000</property>	<!-- 超时时间 -->
		<property name="hibernate.c3p0.max_statements">100</property>	<!-- 最大执行的命令格个数 -->
		<property name="hibernate.c3p0.idle_test_period">30000</property> <!-- 空闲测试时间 -->
		<property name="hibernate.c3p0.acquire_increment">2</property>	<!-- 连接不够用时,每次增加的个数 -->
		 
		 <!-- *********二级缓存*********** -->
	
		 <!-- 
		 	#hibernate.cache.use_second_level_cache false
		 	#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
		  -->
		<!--1) 开启二级缓存 -->
		<property name="hibernate.cache.use_second_level_cache">true</property>
		<!-- 2)使用默认的缓存框架 -->
		<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
		<!-- 开启查询缓存 ,要在class-cache之前-->
		<property name="hibernate.cache.use_query_cache">true</property>
		<!-- 3)指定哪一些类要开启二级缓存 -->
		<class-cache usage="read-write" class="com.bighuan.b_second_cache.Dept"/>
		<class-cache usage="read-write" class="com.bighuan.b_second_cache.Employee"/>
		<!-- 集合缓存 ,集合缓存的元素对象也要加入到二级缓存中-->
		<collection-cache usage="read-write" collection="com.bighuan.b_second_cache.Dept.emps"/>
		
		<!-- 3. 加载所有映射 
		<mapping resource="cn/itcast/a_hello/Employee.hbm.xml"/>
		-->
	</session-factory>
</hibernate-configuration>

4)缓存策略

<class-cache usage="read-only"/>     放入二级缓存的对象,只读;
<class-cache usage="nonstrict-read-write"/>  非严格的读写
<class-cache usage="read-write"/>    读写; 放入二级缓存的对象可以读、写;
<class-cache usage="transactional"/>   (基于事务的策略)

5)集合缓存

集合缓存的元素对象也加入到二级缓存

6)查询缓存

list() 默认情况只会放入缓存,不会从一级缓存中取! 使用查询缓存,可以让list()查询从二级缓存中取!

7)测试代码

package com.bighuan.b_second_cache;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

public class App_second_cache {

	private static SessionFactory sf;
	static {
		sf = new Configuration().configure().addClass(Dept.class)
				.addClass(Employee.class) // 测试时候使用
				.buildSessionFactory();
	}

	//二级缓存:代码执行结果是只有一行查询代码,说明缓存起作用了
        //select dept0_.deptId as deptId0_0_, dept0_.deptName as deptName0_0_ from t_dept dept0_ where dept0_.deptId=?
      @Test
	public void testSecondCache() {
		Session session1 = sf.openSession();
		session1.beginTransaction();

		Dept dept=(Dept) session1.get(Dept.class, 1);
		
		session1.getTransaction().commit();
		session1.close();
		
		Session session2 = sf.openSession();
		session2.beginTransaction();

		Dept dept2=(Dept) session2.get(Dept.class, 1);
		
		session2.getTransaction().commit();
		session2.close();
	}
	
	@Test
	public void testSecondCache2() {
		Session session1 = sf.openSession();
		session1.beginTransaction();

		Dept dept=(Dept) session1.get(Dept.class, 1);
		dept.setDeptName("游戏部");
		
		session1.getTransaction().commit();
		session1.close();
		
	}
	
	@Test
	public void listCache() {
		Session session1 = sf.openSession();
		session1.beginTransaction();
		// HQL查询  【setCacheable  指定从二级缓存找,或者是放入二级缓存】
		Query q = session1.createQuery("from Dept").setCacheable(true);
		System.out.println(q.list());
		session1.getTransaction().commit();
		session1.close();
		
		
		Session session2 = sf.openSession();
		session2.beginTransaction();
		q = session2.createQuery("from Dept").setCacheable(true);
		System.out.println(q.list());  // 不查询数据库: 需要开启查询缓存
		session2.getTransaction().commit();
		session2.close();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值