码迷,mamicode.com
首页 > Web开发 > 详细

Hibernate二级缓存以及ehcache的搭建配置

时间:2015-02-07 21:45:29      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:hibernate   二级缓存   ehcache   sessionfactory   cache   

前言

        这次主要复习Hibernate的二级缓存的相关知识,配置以及使用。二级缓存主要采用第三方的ehcache,也将介绍ehcache缓存的相关配置属性以及在项目中的搭建,具体的项目查看下一篇的  Maven搭建SpringMVC+Hibernate项目详 的文章。(之前使用过Hibernate的二级缓存,但是没自己搭建和研究过,现在花了半天时间搭建了一下,写下来供大家参考)

1、Hibernate二级缓存

     Hibernate包括两个级别的缓存:

        1、一级缓存:默认总是启用的session级别的。

         2、二级缓存:可选的SessionFactory级别的。

       Session级别的以及缓存总是有效的,当应用保持持久化实体、修改持久化实体时,Session并不会吧这种改变flush到数据库,而是缓存在当前Session的一级缓存中,除非程序显示调用session的flush方法,或者查询关闭session时,才会把这先改变一次性的flush到底层数据库,这样可以减少与数据库的交互,从而提高数据库的访问性能。

      SessionFactory级别的二级缓存是全局的,应用的所有的Seeion都共享这个二级缓存,当Session需要抓取数据时,Session就会优先从二级缓存中抓取。(主要包括实体缓存,查询缓存)。

2、适用范围

      主要适合以下数据放入二级缓存:

           1. 很少被修改,大量查询的

            2. 不是很重要的数据,允许出现偶尔并发访问的

3、Hibernate二级缓存的配置

              Hibernate的二级缓存主要使用第三方缓存插件,这里主要使用Ehcache二级缓存。

         首先、我们需要映入ehcache包以及hibernate-ehcache包,maven的pom.xml映入如下:

         

               <!-- hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>4.3.8.Final</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-ehcache</artifactId>
			<version>4.3.8.Final</version>
		</dependency>
		
		<!-- 二级缓存ehcache -->
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>2.9.0</version>
		</dependency>

         其次、我们需要在Hibernate的配置文件中设置二级缓存的相关信息

                 

	<!-- 开启二级缓存 ehcache -->
	<prop key="hibernate.cache.use_second_level_cache">true</prop>
	<!-- 开启查询的二级缓存  如果不需要就不设置-->
	<prop key="hibernate.cache.use_query_cache">true</prop>
	<!-- Hibernate4.0以上设置factory -->
	<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
	<!-- 二级缓存 ehcache的配置文件位置 -->
	<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>

            一般Hibernate的二级缓存实体和属性的缓存映射,如果需要将查询数据也二级缓存,需要使用hibernate.cache.use_query_cache开启。

4、Ehcache的配置

      ehcache.xml的配置文件如下:

     

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
	
	<diskStore path="java.io.tmpdir/ehcache" />
	<!-- DefaultCache setting. -->
     <defaultCache
            maxElementsInMemory="1000"
            eternal="false"
            timeToIdleSeconds="300"
            timeToLiveSeconds="300"
            maxElementsOnDisk="1000000"
            overflowToDisk="true" 
            memoryStoreEvictionPolicy="LRU">
            
    </defaultCache>

	<!-- Special objects setting. -->
	<!-- 
	<cache 
	     name="org.andy.work.entity.AcctUser"
		 maxElementsInMemory="2"
		 memoryStoreEvictionPolicy="LRU" 
		 eternal="true" 
		 diskPersistent="false"
		 overflowToDisk="false" 
		 maxElementsOnDisk="1000000" /> -->



</ehcache>

第一段是配置默认的ehcache二级缓存信息,第二段是特殊的配置(需要配置特殊时)。

4.1、配置详解

    name:缓存名称。
    maxElementsInMemory:缓存最大个数。
    eternal:对象是否永久有效,一但设置了,timeout将不起作用。
    timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
    timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
   overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
   diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
   maxElementsOnDisk:硬盘最大缓存个数。
   diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
   diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
   memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
   clearOnFlush:内存数量最大时是否清除。

   注:java.io.tmpdir目录为:C:\Users\登录用户\AppData\Local\Temp\(window环境中),所以上面在我的电脑下的目录如下(已经有缓存内容):

       技术分享

     当然存储位置我们可以随意的配置如:   <diskStore path="D:/ehcache" />  就是在D盘下的ehcache目录了。

5、配置需二级缓存实体和属性

      这里只介绍注解形式的,xml形式的不说了,大多数公司都用注解。

    在实体类和实体的那些集合属性上启用二级缓存使用

              @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

   注:如果一个实体需要二级缓存,若该实体含有<set...>,<list...>等属性时,也必须要指定缓存策略。

       如下:

     

package org.andy.work.entity;

// Generated 2015-2-3 10:43:00 by Hibernate Tools 4.0.0

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

/**
 * AcctUser generated by hbm2java
 */
@Entity
@Table(name = "acct_user", catalog = "work")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class AcctUser implements java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6980093847795726310L;
	private String id;
	private String nickName;
	private String telephone;
	private Date registerTime;
	private Set<AcctRole> acctRoles = new HashSet<AcctRole>(0);

	public AcctUser() {

	}

	public AcctUser(String id, String nickName) {
		this.id = id;
		this.nickName = nickName;
	}

	public AcctUser(String id, String nickName, String telephone,
			Date registerTime, Set<AcctRole> acctRoles) {
		this.id = id;
		this.nickName = nickName;
		this.telephone = telephone;
		this.registerTime = registerTime;
		this.acctRoles = acctRoles;
	}

	@Id
	@Column(name = "id", unique = true, nullable = false, length = 36)
	public String getId() {
		return this.id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@Column(name = "nick_name", nullable = false)
	public String getNickName() {
		return this.nickName;
	}

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}

	@Column(name = "telephone")
	public String getTelephone() {
		return this.telephone;
	}

	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "register_time", length = 19)
	public Date getRegisterTime() {
		return this.registerTime;
	}

	public void setRegisterTime(Date registerTime) {
		this.registerTime = registerTime;
	}

	@JsonIgnoreProperties(value={"acctUsers", "acctAuthorities"})
	@ManyToMany(fetch = FetchType.LAZY)
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	@JoinTable(name = "acct_user_role", catalog = "work", joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) })
	public Set<AcctRole> getAcctRoles() {
		return this.acctRoles;
	}

	public void setAcctRoles(Set<AcctRole> acctRoles) {
		this.acctRoles = acctRoles;
	}

}

5.1、缓存usage事务隔离机制

        Usage提供缓存对象的事务隔离机制有如下几种:

        (NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)

      ehcache不支持transaction事务机制,但其他三种可以使用:

       read-only::

                 无需修改, 那么就可以对其进行只读 缓存,注意,在此策略下,如果直接修改数据库,即使能够看到前台显示效果,

             但是将对象修改至cache中会报error,cache不会发生作用。另:删除记录会报错,因为不能在read-only模式的对象从cache中删除。

      read-write: 

                   需要更新数据,那么使用读/写缓存 比较合适,前提:数据库不可以为serializable transaction isolation level(序列化事务隔离级别)

     nonstrice-read-write:

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

6、使用查询缓存

      查询缓存所缓存的key值就是查询所使用的HQL或SQL语句,需要注意的是:查询缓存不仅要求所使用的HQL语句、SQL语句相同,甚至是要求所传入的参数也相同,Hibernate才能从缓存中查去数据。

   查询缓存有如下两步:

      1、查询缓存不不仅开启 hibernate.cache.use_query_cache

      2、还需要在查询时使用  setCacheable(true)

    

	public List<AcctUser> findAll() {
		List<AcctUser> acctUsers = this.getCurrentSession().createQuery("from AcctUser").setCacheable(true).list();
		
		return acctUsers;
	}



Hibernate二级缓存以及ehcache的搭建配置

标签:hibernate   二级缓存   ehcache   sessionfactory   cache   

原文地址:http://blog.csdn.net/fengshizty/article/details/43603611

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!