先了解一下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目录下:
xml version ="1.0" encoding ="UTF-8" ?>
< ehcache >
< diskStore path ="java.io.tmpdir" />
< defaultCache
maxElementsInMemory ="10000"
eternal ="false"
overflowToDisk ="true"
timeToIdleSeconds ="300"
timeToLiveSeconds ="180"
diskPersistent ="false"
diskExpiryThreadIntervalSeconds = "120" />
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上配置。
@Entity
@Cache (usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Forest { ... }
@OneToMany (cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn (name= "CUST_ID" )
@Cache (usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public SortedSet getTickets() {
return tickets;
}
@Cache (
CacheConcurrencyStrategy usage(); (1 )
String region() default "" ; (2 )
String include() default "all" ; (3 )
)
(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
---------------------------------------
相关推荐
而当我们谈论“JPA-5 使用二级缓存”时,我们是在讨论如何利用JPA的一个高级特性,即二级缓存,来提升应用的性能。 一级缓存是每个EntityManager实例内的缓存,它是默认开启的,并且是事务性的。一级缓存存储了在...
在本文中,我们将深入探讨如何在Spring Boot 2.1.4.RELEASE项目中结合JPA(Java Persistence API)和Hibernate实现Redis作为二级缓存。首先,我们需要理解这些技术的基本概念。 Spring Boot 是一个用于简化Spring...
- 其他注解如`@Table`、`@Cache`等用于配置表名和其他缓存策略。 ### 总结 通过上述步骤,我们成功地使用JPA注解实现了联合主键的功能。这种方式不仅简化了联合主键的实现过程,还提高了代码的可读性和维护性。...
通过更新EclipseLink的库文件,并清理服务器缓存,可以解决由JPA注入问题导致的运行时异常。对于开发和维护基于JPA的应用,理解这些问题的根源和解决方法至关重要,以确保应用程序的稳定性和数据的完整性。
- **一级缓存(First-Level Cache)**: 每个实体管理器都有自己的缓存,保存着实体实例,提高效率,减少对数据库的访问。 - **二级缓存(Second-Level Cache)**: 可选特性,允许跨会话共享数据,提高了性能,但需要...
- **缓存(Cache)**: JPA支持一级缓存(实体管理器级别)和二级缓存(全局应用级别)来提高性能。 - **懒加载(Lazy Loading)**: 避免在初始化实体时加载关联数据,只在需要时才进行加载。 - **批处理(Batch ...
- **第二级缓存(Second-Level Cache)**: 提高性能,减少数据库访问。 - **多态性(Polymorphism)**: 支持不同类型的实体在同一查询结果中。 - **实体图形(Entity Graph)**: 控制加载特定的实体属性集。 - **...
10. **缓存机制**:了解JPA的缓存层次,包括第一级缓存(First Level Cache)和第二级缓存(Second Level Cache),以及如何利用它们提高性能。 通过阅读JPA.chm的帮助文档,你将全面了解JPA的核心特性和最佳实践,...
除了对 JPA 标准的支持之外,OpenJPA 还提供了非常多的特性和工具支持让企业应用开发变得更加简单,减少开发者的工作量,包括允许数据远程传输/离线处理、数据库/对象视图统一工具、使用缓存(Cache)提升企业应用...
9. **二级缓存(Second-Level Cache)**:探讨如何利用JPA的二级缓存提高应用程序的性能。 10. **实体监听器(Entity Listeners)**:学习如何使用实体监听器来执行特定的业务逻辑,如在插入、更新或删除时触发某些...
默认情况下,Spring Cache会基于方法参数的哈希值生成缓存Key,但有时这可能不满足需求。可以通过实现`KeyGenerator`接口来自定义Key生成逻辑,确保Key与业务逻辑紧密关联,提高缓存的命中率。 4. **测试接口与...
在缓存管理方面,Spring 提供了 Spring Cache抽象层,可以方便地集成各种缓存实现,如Ehcache、Hazelcast或Redis。 **Ehcache** 是一个广泛使用的Java缓存库,适合在内存中存储数据。它提供了一种快速访问最近使用...
- **缓存机制**: 第一级缓存(Entity Manager Cache)和第二级缓存(Hibernate的Session Factory Cache)提高查询性能。 - **批处理(Batch Processing)**: 通过设置批处理大小,一次处理多个SQL语句,提高批量操作...
3. 在实体类上添加`@Cacheable`或`@Cache`注解,声明哪些实体类或属性需要缓存。 4. 对于特定查询,可以使用`@CacheRegion`注解来定义查询结果的缓存区域。 二级缓存能有效减少对数据库的访问,提高性能,但需要...
配置文件中设置 `spring.cache.type` 指定缓存实现。 以上就是 SpringBoot 框架与其他组件结合的基础知识。在实际开发中,还需要根据项目需求进行深入学习和实践,理解每个组件的核心概念,以及它们在 Spring Boot ...
7. **缓存机制**:讲解JPA的缓存层次结构,包括一级缓存(First-Level Cache)和二级缓存(Second-Level Cache),以及如何配置和优化缓存性能。 8. **转换和事件监听**:探讨实体转换(Entity Transformer)和实体...
@QueryHints({ @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_CACHEABLE, value = "true") }) List<YourEntity> findByCustomCriteria(Criteria criteria) { // custom criteria query } ``` 压缩包中的...
Java中常用的缓存库有Ehcache、Guava Cache以及Spring Data Redis等。这里我们以Ehcache为例,讨论如何构建一个简单的分页缓存系统。 1. **Ehcache配置**:首先,我们需要在项目中引入Ehcache的依赖,并配置一个...
`<properties>`标签内设置了一些Hibernate特定的属性,例如禁用二级缓存和更新ID生成器映射策略。 接下来,创建一个表示持久化实体的Java类。使用`@Entity`注解标记此类为JPA实体,同时为每个需要持久化的字段添加...
在Spring Boot 2.0中,Ehcache是一个流行的、高性能的本地缓存解决方案,用于提升应用程序性能。本文将深入探讨如何在Spring Boot项目中集成并使用Ehcache进行数据缓存。 首先,Ehcache是由Talend公司维护的一个...