`

hibernate + jpa @Cache

    博客分类:
  • jpa
 
阅读更多

先了解一下cache基础:

 

一级缓存

Hibernate 的一级缓存是由 Session 提供的,因此它只存在于 Session 的生命周期中,当程序调用 save(),update(),saveorupdate() 等方法 及调用查询接口 list,filter,iterate 时,如 session 缓存中还不存在相应的对象, Hibernate 会把该对象加入到一级缓存中,
Session 关闭的时候该 Session 所管理的一级缓存也会立即被清除
Hibernate 的一级缓存是 Session 所内置的,不能被卸载,也不能进行任何配置
 
二级缓存配置:    
  
1 、首先要打开二级缓存,在 hibernate.cfg.xml 中添加如下配置:    
<property name="hibernate.cache.use_second_level_cache">true</property>  
  
2 Hibernate 的二级缓存使用第三方的缓存工具来实现,所以我们需要指定 Hibernate 使用哪个    
   缓存工具。如下配置指定 Hibernate 使用 EhCache 缓存工具。    
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>  
  
3 Hibernate 在默认情况下并不会对所有实体对象进行缓存,所以,我们需要指定缓存哪些对象,    
在实体对象的映射文件中(相应的 <class> 标签内部),添加如下配置:    
<cache usage="read-only"/>  
  
usage="read-only" 是“只读”缓存策略。    
  
注意,这个 <cache> 标签只能放在 <class> 标签的内部,而且必须处在 <id> 标签的前面!!!    
这个 <cache> 标签放在哪些 <class> 标签下面,就说明会多这些类的对象进行缓存    
  
4 、对于第 3 步,有一个可选的方案是在 hibernate.cfg.xml 文件中指定哪些类的对象需要缓存,    
   而不需要使用 <cache> 标签来指定。如:    
   hibernate.cfg.xml 中添加如下配置:    
   <class-cache class="com.bjsxt.hibernate.Classes" usage="read-only" />  
     
   注意,这个 <class-cache> 标签必须放在 <mapping> 标签的后面!!    
 
Hibernate缓存配置
_____________________________________________________________________________________
Hibernate的缓存分为:
  一级缓存:在Session级别的,在Session关闭的时候,一级缓存就失效了。
  二级缓存:在SessionFactory级别的,它可以使用不同的缓存实现,如EhCache 、JBossCache、OsCache等。
  
缓存的注释写法如下,加在Entity的java类上:
  @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  
缓存的方式有四种,分别为:
  CacheConcurrencyStrategy.NONE
  CacheConcurrencyStrategy.READ_ONLY,只读模式,在此模式下,如果对数据进行更新操作,会有异常;
  CacheConcurrencyStrategy.READ_WRITE,读写模式在更新缓存的时候会把缓存里面的数据换成一个锁,其它事务如果去取相应的缓存数据,发现被锁了,直接就去数据库查询;
  CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,不严格的读写模式则不会的缓存数据加锁;
  CacheConcurrencyStrategy.TRANSACTIONAL,事务模式指缓存支持事务,当事务回滚时,缓存也能回滚,只支持JTA环境。
  
另外还有如下注意事项:
  1、查询缓存需要在Query的相应方法执行前加上这么一句:
  query.setCacheable(true);
  在使用Hibernate时,获得的query有setCacheable 方法,可以设置使用缓存,但当使用JPA时,javax.persistence.Query并没有setCacheable方法,此时如果JPA的实现 是Hibernate时,可以将其进行如下转化,再调用setCacheable方法(如果JPA的实现是其它ORMAP框架,就不知道怎么做了)。
if (query instanceof org.hibernate.ejb.QueryImpl) {
    ((org.hibernate.ejb.QueryImpl) query).getHibernateQuery().setCacheable(true);
}

  2、还有就是查询缓存的查询执行后,会将查询结果放入二级缓存中,但是放入的形式是以ID为Key,实例作为一个Value。
  3、hibernate的配置文件中需加入如下信息:
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />

 

缓存映射(Cache mappings)


类或者集合映射的“<cache> 元素”可以有下列形式:

<cache 

 usage="transactional|read-write|nonstrict-read-write|read-only" (1)

/>

 

(1)
usage 说明了缓存的策略: transactional read-write nonstrict-read-write read-only


另外(首选?), 你可以在hibernate.cfg.xml中指定<class-cache> <collection-cache> 元素。
这里的usage 属性指明了缓存并 发策略(cache concurrency strategy)

只读 缓存(read only)


如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。

<class name="eg.Immutable" mutable="false">

 <cache usage="read-only"/>

 ....

</class>




读/写缓存( read/write)


如果应用程序需要更新数据,那么使用读/写缓存 比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。 如果在JTA环境中使用缓存,你必须指定hibernate.transaction.manager_lookup_class 属 性的值, 通过它,Hibernate才能知道该应用程序中JTA的TransactionManager 的 具体策略。 在其它环境中,你必须保证在Session.close() 、或Session.disconnect() 调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate内置的缓存策略并不支持锁定功能。

<class name="eg.Cat" .... >

 <cache usage="read-write"/>

 ....

 <set name="kittens" ... >

 <cache usage="read-write"/>

 ....

 </set>

</class>

 

非严格读/写缓存(nonstrict read/write)


如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写缓存 策略。如果在JTA环境中使用该策略, 你必须为其指定hibernate.transaction.manager_lookup_class 属性的值, 在其它环境中,你必须保证在Session.close() 、或Session.disconnect() 调用前, 整个事务已经结束

-------------------------------------------------------------------------
在jBPM 中使用不少这样的非严格读/写缓存的处理:
<?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 default-access="field">
  <class name="org.jbpm.context.def.VariableAccess"
         table="JBPM_VARIABLEACCESS"
         lazy="false">
    <cache usage="nonstrict-read-write"/>
    <id name="id" column="ID_"><generator class="native" /></id>
   
    <property name="variableName" column="VARIABLENAME_" />
    <property name="access" column="ACCESS_" />
    <property name="mappedName" column="MAPPEDNAME_" />
  </class>
</hibernate-mapping>

它的ehcache.xml 是这样配置的:
<ehcache>
 <defaultCache
        maxElementsInMemory="100000"
        eternal="true"
        overflowToDisk="false"
        diskPersistent="false"
        />
</ehcache>
 

Hibernate Annotation 中配置EhCache缓存



1.  首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下:
  1. xml  version ="1.0"  encoding ="UTF-8" ?>   
  2. < ehcache >   
  3.  < diskStore  path ="java.io.tmpdir" />     
  4.   < defaultCache   
  5.    maxElementsInMemory ="10000"    
  6.    eternal ="false"    
  7.   
  8.    overflowToDisk ="true"    
  9.   
  10.    timeToIdleSeconds ="300"    
  11.    timeToLiveSeconds ="180"    
  12.    diskPersistent ="false"   
  13.    diskExpiryThreadIntervalSeconds"120" />     
  14. ehcache >   

  2.  在Hibernate配置文件中设置:

<hibernate-configuration> <session-factory> ……<property name=" hibernate . cache.provider_class">org.hibernate.cache.EhCacheProvider </property> <property name="cache.use_second_level_cache">true </property> ……</session-factory> </hibernate-configuration>
        此外,可以把cache.use_second_level_cache设置为false关闭所有的hibernate二级缓存。但此属性对指定<cache>的类缺省为true。

 
   3.  为了使用二级缓存,需要在每一个Hibernate Entity上配置。
  1. @Entity   
  2. @Cache (usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)   
  3. public   class  Forest { ... }  

  1. @OneToMany (cascade=CascadeType.ALL, fetch=FetchType.EAGER)   
  2. @JoinColumn (name= "CUST_ID" )   
  3. @Cache (usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)   
  4. public  SortedSet getTickets() {   
  5.      return  tickets;   
  6. }  

  1. @Cache (   
  2.     CacheConcurrencyStrategy usage();                 (1 )   
  3.     String region()  default   "" ;                       (2 )   
  4.     String include()  default   "all" ;                   (3 )   
  5. )  


(1) usage: 提供缓存对象的事务隔离机制,可选值有以下几种
(NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)
(2) region (optional): 指定缓存的区域,默认是类的全限定名。利用缓存区域,可以更精确的指定每个区域的缓存超前策略。如果指定了缓存区域前缀(在 hibernate.cfg.xml中设置cache.region_prefix属性为一个字符串),则所有的缓存区域名前将加上这个前缀。
(3) include (optional): all to include all properties, non-lazy to only include non lazy properties (default all).

如果不是使用annotation的话,则是在Hbm文件中添加cache usage="read-only"

 

 

---------------------------------------------

本次项目使用hibernate + jpa, 其配置如下:

 

jap的persistence.xml文件

 

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">   
    <persistence-unit name="punit" transaction-type="RESOURCE_LOCAL">
        <provider >org.hibernate.ejb.HibernatePersistence</provider>
        <mapping-file>IptvFeeORM.xml</mapping-file>
        <properties>
            <property name="hibernate.jdbc.batch_size" value="100"/>
            <property name="hibernate.cache.use_second_level_cache"
                      value="true" />
              <property name="hibernate.cache.provider_class"
                  value="net.sf.ehcache.hibernate.EhCacheProvider" />
              <property name="hibernate.cache.use_minimal_puts" value="true"/>
            <property name="net.sf.ehcache.configurationResourceName" value="/hibernate_ehcache.xml"/>
        </properties>
    </persistence-unit>
</persistence>

 

 

cache.xml配置文件:

 

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <diskStore path="./ehcache/hibernate/diskStore" />
    <defaultCache maxElementsInMemory="5000000" eternal="false"
        timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="false"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="1200"
        memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

 

 

spring引用的数据库配置文件 IptvFeeConfig.properties :

 

#database config
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.1.1:1521:love
jdbc.username=you
jdbc.password=me
jdbc.maxActive=5
jdbc.maxIdle=5
jpa.database=ORACLE
jpa.showSql=true
jpa.generateDdl=false
jdbc.getdate.sql=select sysdate from dual

 

spring 里面的配置文件:

 

 

 

<bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:IptvFeeConfig.properties" />
    </bean>
    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceXmlLocation" value="classpath:IptvFeePersistence.xml" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="${jpa.database}" />
                <property name="showSql" value="${jpa.showSql}" />
                <property name="generateDdl" value="${jpa.generateDdl}"></property>
                <property name="databasePlatform" value="org.hibernate.dialect.OracleDialect" />
            </bean>
        </property>
    </bean>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName">
            <value>${jdbc.driver}</value>
        </property>
        <property name="url">
            <value>${jdbc.url}</value>
        </property>
        <property name="username">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
        <property name="maxActive">
            <value>${jdbc.maxActive}</value>
        </property>
        <property name="maxIdle">
            <value>${jdbc.maxIdle}</value>
        </property>
        <property name="testOnBorrow" value="true"/>
        <property name="validationQuery" value="${jdbc.getdate.sql}"/>
       
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"
        proxy-target-class="true" />
    <bean id="org.springframework.jdbc.core.JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="com.domain.repository.Repository"
        class="com.repository.RepositoryJpaImpl">
        <property name="jdbcTemplate" ref="org.springframework.jdbc.core.JdbcTemplate" />
    </bean>

 

 

 

实体class

@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class BillContent extends AbstractPersistable implements Persistable

分享到:
评论

相关推荐

    SpringBoot操作数据库jpa-SB系列之006-配套项目

    ​2 JPA有两个重要的儿子Hibernate ,iBATIS Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装。 hibernate劣势 难以使用数据库的一些功能 满足不了程序对cache的需求 耦合度高 ...

    Spring_Hibernate_JAVAX_Annotation注解

    SSH开发注解大全,涉及到的注解内容涵盖AspectJ,Batch,Spring,Cache,Data-Jpa,Integration,JMX,Roo,Security,Test,MVC,WS,JSR(168,222,224,250,299,303,314,317,330,220),Hibernate 3

    fhs-framework快速开发平台-其他

    fhs-framwork是一个集成了国内外诸多优秀开源项目的快速开发平台,除了在常规快速开发平台提供用户,角色,权限,...缓存:jetcache+spring data cache 分布式任务:shedlock 文档:swagger 演示账号密码:admin 123456

    interview-preparation:本指南适用于准备面试的Java后端开发人员。 它包括来自Core Java,Spring MVC,SpringBoot,Docker,Git,HTTP Cache,DB,JPA,Hibernate,Security,HTTP等的主题

    面试准备指南 我以前就阅读的主题准备了一些笔记,以供将来参考。 我认为这对希望在面试前进行最后一分钟修订的每个人都是有用的。 因此创建了这个仓库 这个仓库的内容是我写的,或者是从一些参考网站或论坛上获得的...

    spring-memcache-sample:示例 Spring 项目,使用基于 memcached 的缓存后端缓存注释

    Spring Memcache 示例一个开箱即用的小示例,用于演示在 Spring MVC 驱动的 REST API 上使用 Spring 的@Cache注释。使用的库以下是演示中使用的最重要库的列表: 图书馆版本评论弹簧框架4.1.2. 发布弹簧芯弹簧数据-...

    fhs-framework快速开发平台 v2.0.4

    授权方式: 开源软件 界面语言: 简体中文 ...缓存:jetcache+spring data cache 分布式任务:shedlock 文档:swagger 演示账号密码:admin 123456 fhs-framwork截图 相关阅读 同类推荐: 站长常用源码

    spring boot 所有‘demo,打包下载’

    spring boot 学习的最佳选择,包含了jpa ,tomcat ,cache, ant ,hibernate4 , jetty,war,web ,xml 等

    jboss seam

    Seam为持久化集成了JPA和Hibernate 3,为轻量化的异步性集成了EJB Timer Service和Quartz,为工作流集成了jBPM,为业务规则集成了JBoss规则,为电子邮件集成了Meldware Mail,为完整的文本搜索集成了Hibernate ...

    从零开始学Spring Boot

    1.9 JPA - Hibernate 1.10 使用JPA保存数据 1.11 使用JdbcTemplate 1.12 Spring Boot修改端口号 1.13 Spring Boot配置ContextPath 1.14 Spring Boot改变JDK编译版本 1.15 处理静态资源(默认资源映射) 1.16 处理静态...

    springboot的demo

    包含sping与jpa、hibernate、mybatis、shiro、sitemesh、websocket、websocket-netty-server、cache-ehcache、cache-redis等一些等整合样例

    spring-boot-cache

    Spring Boot示例Hibernate模式和数据实体的ddl模式application setting : spring.jpa.hibernate.ddl-auto: create-drop 通过data.sql插入数据path= src/main/resources/sql/data.sql跑步mvn spring-boot:run

    Spring 3.x 中文开发手册.pdf

    6、hibernate4支持,不感兴趣 7、spring测试框架和2,3,4的结合 8、spring配置文件中namespace的事情,不感兴趣 9、非标准setter类也可以注入了。。。不感兴趣 10、支持Servlet3的某个东东,可以写程序直接启动webapp...

    java开发常用jar包

    hibernate-jpa-2.0-api-1.0.1.Final.jar jackson-annotations-2.5.0.jar jackson-core-2.5.0.jar jackson-databind-2.5.0.jar javassist-3.11.0.GA.jar javassist-3.15.0-GA.jar jboss-logging-3.1.0....

    zxframe的demo

    支持JPA:继承hibernate的便捷操作和mybatis的sql集中编写or管理;支持乐观锁 *.支持多层次缓存:本地一级缓存,本地全局二级缓存,远程缓存,查询缓存,方法级别缓存 *.支持缓存融入事务,业务异常不提交缓存数据 *...

    javaweb项目常用jar包

    hibernate-jpa-2.1-api-1.0.0.Final.jar httpclient-4.0.jar httpclient-4.1.1.jar httpcore-4.0.jar httpcore-4.1.jar httpcore-nio-4.0.jar httpmine-4.0.jar ibatis-2.3.4.726.jar jackson-all-1.7.4.jar...

    play框架手册

    用hibernate持久化对象模型 - 69 - 保持模型stateless - 70 - 07.JPA持久化 - 70 - 启动JPA实体管理器 - 70 - 获取JPA实体管理器 - 70 - 事务管理 - 71 - play.db.jpa.Model支持类 - 71 - 为GenreicModel定制id映射 ...

    play framework 框架手册 word 版

    用hibernate持久化对象模型 - 69 - 保持模型stateless - 70 - 07.JPA持久化 - 70 - 启动JPA实体管理器 - 70 - 获取JPA实体管理器 - 70 - 事务管理 - 71 - play.db.jpa.Model支持类 - 71 - 为GenreicModel定制id映射 ...

    zxframe demo.rar

    支持JPA,既有hibernate的便捷操作,又有mybatis的sql集中编写or管理的风格;支持乐观锁 *.支持防缓存穿透,防缓存击穿,防缓存雪崩 *.支持多层次缓存:本地一级缓存,本地全局二级缓存,远程缓存,查询缓存,方法...

    培训体系管理系统-oracle-ssh

    javassist.jar jaxen-1.1-beta-7.jar jboss-cache.jar jboss-common.jar jboss-jmx.jar jboss-system.jar jdbc2_0-stdext.jar jgroups-2.2.8.jar jstl.jar jta.jar jxl.jar log4j-1.2.11.jar log4j-1.2.14.jar mysql...

    Manning.Spring.in.Action.4th.Edition.2014.11.epub

    11.3. Automatic JPA repositories with Spring Data 11.3.1. Defining query methods 11.3.2. Declaring custom queries 11.3.3. Mixing in custom functionality 11.4. Summary Chapter 12. Working with NoSQL ...

Global site tag (gtag.js) - Google Analytics