Hibernate(5.3.7)的二级缓存

hibernate提供了两个级别的缓存。
第一个级别:Session级别,属于事务范围,由hibernate管理,一般无须干预。
第二个级别:SessionFactory级别,属于进程范围,是一个可插拔缓存插件,由工厂管理。

原理与分类:
根据对象的ID加载和缓存数据。当执行查询获得的结果集为实体对象的时候,hibernate会把获得的实体对象按照ID存到二级缓存中。
在访问指定对象时,先从一级缓存中找,找到就用,没找到就转到二级缓存中找(需要配置和启用二级缓存),找到就用。没找到就查询数据库,然后放在一级和二级缓存中。

内置缓存:hibernate自带,不可卸载。在hibernate初始化阶段将映射元数据和预定义的SQL语句放在sessionFactory的缓存中,内置缓存是只读的。
外置缓存(二级):可配置的缓存插件。默认不使用,其中的数据是数据库数据的复制。

二级缓存的结构:
分四类:
1、Class Cache Region:类级别缓存,主要用于存储PO(实体)对象。
2、Collection Cache Region:集合级别缓存,用于存储集合数据。
3、Query Cache Region:查询缓存,会缓存一些常用查询语句的查询结果。
4、Update TimesTamps:更新时间戳缓存,存放与查询结果相关的表在进行操作时的时间戳,hibernate通过更新时间戳缓存区判断被缓存的查询结果是否过期。

缓存的并发访问策略:
1、只读型(Read-Only):提供Serializable数据隔离级别,对于从来不修改的数据可以采用。
2、读写型(Read-Write):提供Read Commited数据隔离级别,对于经常读但很少被修改的数据,可以采用,可防止脏读。
3、非严格读写(Nonstrict-read-write):不保证缓存与数据库中数据的一致性,提供Read Uncommited事务隔离级别,对于极少被修改,且允许脏读的数据,可以采用。
4、事务型(Transactional):提供Repeatable Read事务隔离级别,对于经常读但是少更改的数据,可采用,可防止脏读和不可重复读。

1、EHChache:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,对hibernate查询缓存提供支持。
2、OpenSymphony OSCache:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,提供丰富的缓存数据过期策略,并且对hibernate查询缓存提供了支持。
3、SwarmCache :可作为集群范围内的缓存,不支持hibernate查询缓存。
4、JbossCache:可作为集群范围内的缓存,支持hibernate查询缓存。

二级缓存的配置和使用:
以Hibernate5.3.7中EHCache为例:
1、引入EHCache的JAR包:
lib下的optional下ehcache所有jar包:Jar包
2、引入EHCache的配置文件:配置文件


     (设置缓存数据文件的存储目录)
          
          
           

3、启用二级缓存:
在hibernate配置文件中启用,并指定哪些实体类需要二级缓存。


true

org.hibernate.cache.ehcache.EhCacheRegionFactory

true

	

	

	

class-cache与collection-cache元素需要放在mapping元素之后。

4、创建测试类文件:

/**
	 * 	二级缓存测试(从SessionFactory缓存中取单个对象)
	 */
@Test
	public void test1() {
		//加载配置文件
		Configuration configuration = new Configuration().configure();
		//创建session工厂 
		SessionFactory factory = configuration.buildSessionFactory();
		
		//第一次
		Session session =factory.openSession();
		Transaction trans = session.beginTransaction();
		Customer c1 = session.get(Customer.class,3);
		System.out.println("第一次:"+c1.getName());
		trans.commit();
		session.close();
		System.out.println("====================");
				
		//第二次
		Session session1 = factory.openSession();
		Transaction trans1 = session1.beginTransaction();
		Customer c2 = session1.get(Customer.class,3);
		System.out.println("第二次:"+c2.getName());
		trans1.commit();
		session1.close();		
	}
 
 
 /**
	 * 	二级缓存测试(从SessionFactory缓存中取单个对象下的集合)
	 */
	@Test
	public void test2() {
		//加载配置文件
		Configuration configuration = new Configuration().configure();
		//创建session工厂 
		SessionFactory factory = configuration.buildSessionFactory();
		
		//第一次
		Session session =factory.openSession();
		Transaction trans = session.beginTransaction();
		Customer c1 = session.get(Customer.class,3);
		Set orderSet = c1.getOrderSet();
		System.out.println("第一次:"+c1.getName());
		
		for (Order order : orderSet) {
			System.out.println(order.getAddress());
		}
		
		trans.commit();
		session.close();
		System.out.println("====================");
				
		//第二次
		Session session1 = factory.openSession();
		Transaction trans1 = session1.beginTransaction();
		Customer c2 = session1.get(Customer.class,3);
		Set orderSet1 = c2.getOrderSet();
		System.out.println("第二次:"+c2.getName());
		
		for (Order order : orderSet1) {
			System.out.println(order.getAddress());
		}
		
		trans1.commit();
		session1.close();		
	}
 
 
	/**
	 * 	三级缓存测试(从缓存中取单个对象)
	 */
	@Test
	public void test3() {
		//加载配置文件
		Configuration configuration = new Configuration().configure();
		//创建session工厂 
		SessionFactory factory = configuration.buildSessionFactory();
		
		//第一次
		Session session =factory.openSession();
		Transaction trans = session.beginTransaction();
		Query query = session.createQuery("from Customer where id=3",Customer.class);
		query.setCacheable(true);
		Customer c1 = query.uniqueResult();
		System.out.println(c1.getName());
		trans.commit();
		
		
		System.out.println("===================");
		
		//第二次
		session =factory.openSession();
		Transaction trans1 = session.beginTransaction();
		Query query1 = session.createQuery("from Customer where id=3",Customer.class);
		query1.setCacheable(true);
		c1 = query1.uniqueResult();
		System.out.println(c1.getName());
		trans1.commit();
		
	}

你可能感兴趣的:(JavaEE,Hibernate)