`
fishergay
  • 浏览: 33614 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

spring+hibernate整合ehcache

    博客分类:
  • SSH
 
阅读更多

1.使用ehcache来提高系统的性能,现在用的非常多, 也支持分布式的缓存,在hibernate当中作为二级缓存的实现产品,可以提高查询性能。

2.在之前的struts2.12+Spring3.2+hibernate4.2集成系列的文章中已经集成了ehcachejar包了hibernate4.2当中可以找到ehcache-core-2.4.3.jar hibernate-ehcache-4.2.0.Final.jar

Hibernate 本身支持ehcahce的集成,提对他进行了集成的封装。

3. 在项目的src下面添加ehcache的配置文件ehcache.xml

 

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
	<!--
    Subdirectories can be specified below the property e.g. java.io.tmpdir/one
    -->
    <diskStore path="java.io.tmpdir"/>

    <!--
    Mandatory Default Cache configuration. These settings will be applied to caches
    created programmtically using CacheManager.add(String cacheName)
    -->
    <defaultCache
	     maxElementsInMemory="10000"
	     eternal="false"
	     timeToIdleSeconds="120"
	     timeToLiveSeconds="120"
	     overflowToDisk="true"
	     maxElementsOnDisk="10000000"
	     diskPersistent="false"
	     diskExpiryThreadIntervalSeconds="120"
	     memoryStoreEvictionPolicy="LRU"
     />
    
    <cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
		   maxElementsInMemory="5000" 
	       eternal="true" 
	       overflowToDisk="true" />
	<cache name="org.hibernate.cache.internal.StandardQueryCache"
	       maxElementsInMemory="10000" 
	       eternal="false" 
	       timeToLiveSeconds="120"
	       overflowToDisk="true" />	
	
	<!--
	java文件注解查找cache方法名的策略:如果不指定java文件注解中的region="ehcache.xml中的name的属性值", 
	则使用name名为com.lysoft.bean.user.User的cache(即类的全路径名称), 如果不存在与类名匹配的cache名称, 则用 defaultCache
	如果User包含set集合, 则需要另行指定其cache
	例如User包含citySet集合, 则也需要
	添加配置到ehcache.xml中
	-->    
    <cache name="copierCache" maxElementsInMemory="2000" eternal="false" 
	       timeToIdleSeconds="120" timeToLiveSeconds="120"
	       overflowToDisk="true" />  
	    
</ehcache>

4. 在spring 集成hibernate 的配置文件中,添加如下配置

 

<!-- 开启查询缓存 -->
<prop key="hibernate.cache.use_query_cache">true</prop>
<!-- 开启二级缓存 -->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<!-- 高速缓存提供程序 --> 
<!-- 由于spring也使用了Ehcache, 保证双方都使用同一个缓存管理器 -->
<prop key="hibernate.cache.region.factory_class">
     org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</prop>

5. Spring也使用ehcache, 所以也需要在spring配置文件中添加ehcache的配置

 

<!-- cacheManager, 指定ehcache.xml的位置 --> 
	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation">
        	<value>classpath:ehcache.xml</value>
        </property>
        <!-- 由于hibernate也使用了Ehcache, 保证双方都使用同一个缓存管理器 -->
        <property name="shared" value="true"/>
    </bean>

 

 由于hibernate spring都使用了ehcache, 可以由spring 或者hibernate 来管理ehcache

使用spring管理ehcache的好处是可以使用依赖注入,可以在程序中注入使用,比较方便,因此采用spring管理ehcache比较好, 不过spring hibernate一起使用ehcache的话,会产生两个CacheManager,这样在分布式缓存中会有数据部同步的问题, 需要配置一下,springhibernate公用一个CacheManager

 

EHCache升级到1.2之后,对原来CacheManager的实例化方式进行了一些修改。在之前的EHCache中,只会存在一个CacheManager的实例,所有使用EHCache组件的应用都共享这个实例。

而在EHCache 1.2之后,则提供了对多实例的支持。这样,在有多个功能模块同时使用EHCache的时候就要注意实例方式的选取了。

CacheManager是否为多实例取决于获得CacheManager的方法。如果使用构造方法来获得CacheManager对象的实例,那么就会获得一个新的CacheManager实例。而使用create()方法获得CacheManager实例的时候则会获得singleton的实例(如果还没有创建,它会自动地创建)。

现在,在一个应用中,默认情况下Hibernate会创建一个单独的CacheManager实例,如果在其他功能模块中也需要使用这个CahceManager实例,就需要使用EHCache所提供的singletonCacheProvider。在Hibernate配置文件中的配置方法如下:

在配置hibernate的相关信息里面设置成单实例的CacheManager Factory

 

<!-- 由于spring也使用了Ehcache, 保证双方都使用同一个缓存管理器 -->
<prop key="hibernate.cache.region.factory_class">
     org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</prop>

 spring 配置ehcache里面需要添加这个属性 

 

<!-- 由于hibernate也使用了Ehcache, 保证双方都使用同一个缓存管理器 -->
        <property name="shared" value="true"/>

  

我们来看一下hibernate配置里面 SingletonEhCacheRegionFactory这个类的源代码,
String configurationResourceName = null;
            if ( properties != null ) {
                configurationResourceName = (String) properties.get( NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME );
            }
            if ( configurationResourceName == null || configurationResourceName.length() == 0 ) {
                manager = CacheManager.create();
                REFERENCE_COUNT.incrementAndGet();
            }

我们可以看到 会以默认的配置文件名称 创建一个CacheManager 对象,并且是以CacheManager.create()方法创建的, 说明只会产生一个CacheManager 实例。
再来看一下spring EhCacheManagerFactoryBean这个类的源码
private boolean shared = false;
if (this.shared) {
				this.cacheManager = (is != null ? CacheManager.create(is) : CacheManager.create());
			}
			else {
				this.cacheManager = (is != null ? new CacheManager(is) : new CacheManager());
			}

发现里面有个share的变量, 是否是共享使用CacheManger, 如果是true, 调用的是CacheManager.create()的方法创建CacheManager,false调用 new CacheManager方法会生成多个实例。
再看看CacheManger里面的create方法源码
private static volatile CacheManager singleton;
if (singleton != null) {
            return singleton;
        }
        synchronized (CacheManager.class) {
            if (singleton == null) {
                LOG.debug("Creating new CacheManager with default config");
                singleton = new CacheManager();
            } else {
                LOG.debug("Attempting to create an existing singleton. Existing singleton returned.");
            }
            return singleton;
        }

可以看到CacheManager 定义的变量是static 的,create方面里面做了判断singleton 是否已经创建过。


配置好后, 把项目部署到tomcat上面,以debug的方式启动, 可以debug到源码可以观察CacheManger 的创建过程。

来检验一下缓存是否起作用了,添加一个User类
package com.lysoft.bean.user;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

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

@Entity
@Table(name = "t_user")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="longTimeCache")
public class User implements Serializable {
	private static final long serialVersionUID = 4239100106344646509L;
	private Integer id;
	private String userName;
	private String firstName;
	private Date createTime;

	@Id @GeneratedValue
	public Integer getId() {
		return id;
	}

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

	@Column(length = 50, nullable = false)
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

}


添加了一个注解@Cache, 指定缓存策略是读和写, 并指定使用的缓存区域
在ehcache中添加一个cache配置
<cache name="longTimeCache" maxElementsInMemory="2000" eternal="false" 
       timeToIdleSeconds="300" timeToLiveSeconds="900"
       overflowToDisk="true" />

注意cache标签后面的 name 属性不要换行,换行了会有异常, 我上次不小心换行了, 查了半天文档都没有查到是什么问题,后来找个文件复制了一份对比才知道是换行引起的问题。

默认情况下二级缓存只会对load get 之类的方法缓存, 想list iterator 之类的方法也使用缓存 必须跟查询缓存一起使用, 在UserDaoImpl中重写listAll 方法。
	public List<User> listAll() {
	return getSession().createQuery("from User").setCacheable(true).list();
	}

 log4j 配置文件中 设置成debug级别

在网页中访问http://localhost:8080/SSH2/user/userList.do

第一次访问可以看到debug信息如下:

[2013-04-13 22:00:08.082] [DEBUG] [http-8080-1] [org.hibernate.cache.internal.StandardQueryCache:137] - Query results were not found in cache

[2013-04-13 22:00:08.113] [DEBUG] [http-8080-1] [org.hibernate.SQL:104] - 

    select

        user0_.id as id1_0_,

        user0_.createTime as createTi2_0_,

        user0_.firstName as firstNam3_0_,

        user0_.userName as userName4_0_ 

    from

        t_user user0_

缓存中找不到 Query results were not found in cache 发出了查询sql

第二次访问:

Debug日志 

Checking query spaces are up-to-date: [t_user]

Returning cached query results

从缓存中找到了查询结果 直接返回了,没有发出查询sql

分享到:
评论

相关推荐

    Struts2+Spring+Hibernate+Ehcache+AJAX+JQuery+Oracle 框架集成用户登录注册Demo工程

    1.通过google ehcache-spring-annotatios.jar自动注解方式实现整合Spring+Ehcache。 2.Action里通过struts2-spring-plugin.jar插件自动根据名字注入。 3.Ajax无刷新异步调用Struts2,返回Json数据,以用户注册为例。...

    Spring+Hibernate+ehcache整合

    在"Spring+Hibernate+ehcache整合"项目中,开发者已经完成了一个将这三个框架集成的基础工程。虽然Struts没有被明确提及,但通常在Web开发中,Spring与Struts结合可以构建更完整的MVC架构。这个整合项目可能包含以下...

    maven整合spring+hibernate+mqsql+ehcache

    maven环境下如何整合spring+hibernate+mysql+ehcache的方法

    最新版本的Struts2+Spring4+Hibernate4框架整合

    整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6。 此外,还有:log4j、slf4j、junit4、ehcache等知识点。 项目...

    Struts2+Spring2.5+Hibernate3+Freemarker框架整合

    整合S2SH+Freemarker+oscache,后台用Spring管理各个bean,Hibernate做数据库持久化,viewer用Freemarker。整合中对Struts2,Hibernate,Spring都采用Annotation进行注解类。

    配置Spring+hibernate使用ehcache作为second-levelcache.docx

    Ehcache 是一个开源的缓存框架,提供了一个高性能的缓存解决方案,可以与 Hibernate 和 Spring 整合使用,以提高应用程序的性能。 缓存的重要性 在 Web 应用程序中,数据库访问是性能瓶颈之一。数据库访问需要消耗...

    SpringMVC+hibernate+spring+shiro+Ehcache所需jar包

    这个压缩包"SpringMVC+hibernate+spring+shiro+Ehcache所需jar包"提供了搭建基于SpringMVC、Spring 4.2、Hibernate 4.3、Shiro 1.2.4和Ehcache 2.0的基础组件,这些都是Java开发中非常流行和实用的工具。接下来,...

    spring3 hibernate4 ehcache实例

    本文将详细介绍如何在Spring3和Hibernate4环境下整合Ehcache,实现数据缓存功能,以提高应用性能。 1. **Spring3与Hibernate4整合** 在Spring3中配置Hibernate4,我们需要在配置文件中定义SessionFactory,并使用...

    ssh,struts+hibernate+spring+ehcache集成

    例如,为了使用Ehcache,需要在Spring配置文件中添加Ehcache的相关bean,然后在Hibernate的SessionFactory配置中启用二级缓存。此外,还需要在Struts的Action中调用由Spring管理的业务服务,这些服务通常会利用...

    Struts+Spring+Hibernate整合

    Struts、Spring 和 Hibernate 是Java Web...综上所述,Struts+Spring+Hibernate整合能够构建出高效且易于维护的Java Web应用,对于初学者来说,这是一个很好的学习实例,可以深入理解MVC架构和企业级开发的实践方法。

    jar包整合:Springmvc+hibernate+Ehcache+shior+mysql+Oracle+fastjson

    标题中的"jar包整合:Springmvc+hibernate+Ehcache+shiro+mysql+Oracle+fastjson"指的是一个综合性的Java项目,它集成了多种技术框架,用于构建高效、可扩展的Web应用。让我们逐一解析这些技术的核心知识点: 1. **...

    基于Struts2+Spring+Hibernate+MySql的注册登录系统.zip

    整合EhCache与Spring和Hibernate非常简单,Spring提供了配置支持,使得EhCache的初始化和管理变得自动化。通过设置配置文件,可以指定哪些数据需要被缓存,以及缓存的策略,如过期时间、更新策略等。 总的来说,...

    springmvc+spring+hibernate环境

    Hibernate的二级缓存可以提高数据读取效率,常见的缓存提供商有EhCache和Redis。 在"springmvc+spring+hibernate环境"中,配置文件通常会包括Spring的配置文件(如applicationContext.xml)、Spring MVC的配置文件...

    spring+springMVC+hibernate+cxf+定时器+ehcache个人整合

    这里我们关注的是一个基于Spring、SpringMVC、Hibernate、CXF、Quartz定时器和Ehcache的整合项目。这个项目结合了这些技术,以实现一个高效、灵活且可扩展的企业级应用。下面将详细介绍每个组件及其在整体架构中的...

    spring3+hibernate4+struts2+dbcp+mysql+json+ehcache+dom4j 合集包

    它与Spring和Hibernate整合良好,可以实现业务逻辑、数据访问和视图的分离,提供强大的拦截器机制和丰富的插件体系。 4. **DBCP连接池**:Apache Commons DBCP是Apache提供的数据库连接池组件,用于管理和复用...

    Maven项目Spring4+Hibernate4+shiro+Ehcache项目集成

    在本项目中,我们主要探讨的是一个基于Maven构建的Java Web应用,它整合了Spring 4、Hibernate 4、Apache Shiro以及Ehcache等多个关键框架,旨在实现用户角色菜单管理的功能。以下是对这些技术及其集成应用的详细...

    DWZ+springMvc+hibernate+ehcache 简易的后台管理+即时通讯

    标题中的“DWZ+springMvc+hibernate+ehcache 简易的后台管理+即时通讯”揭示了这个项目采用的技术栈,包括前端框架、后端框架、持久层框架以及缓存管理工具。让我们逐一深入理解这些技术点: 1. **DWZ**:DWZ全称为...

    spring+hibernate整合

    整合 Spring 和 Hibernate 的主要目的是利用 Spring 的管理能力来控制 Hibernate 的 Session,避免直接在业务逻辑代码中进行数据库会话的创建和关闭,从而提高代码的可测试性和可维护性。下面将详细介绍整合过程中的...

    Spring4MVC+Hibernate4+Freemarker+Ehcache+EASYUI

    本项目整合了Spring4MVC、Hibernate4、Freemarker、Ehcache以及EasyUI,旨在提供一个强大的后端框架与美观的前端界面,同时优化性能。接下来,我们将详细讨论这些技术组件及其在项目中的作用。 **Spring4MVC**: ...

    spring4.1.6+hibernate4.3.9+struts2.3.20整合

    整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.20 + Spring4.1.6 + Hibernate4.3.9。 此外,还有:log4j、slf4j、junit4、ehcache等知识点。 项目...

Global site tag (gtag.js) - Google Analytics