hibernate ehcache 配置指导
来源:互联网 发布:数据库视频百度云 编辑:程序博客网 时间:2024/06/05 00:34
缓存由ORM框架提供以便用户可以获得更快速的访问速度,同时框架本身也减少了数据库查询操作。hibernate同样在两个层上提供了缓存的功能。
一级缓存:这是在session范围内默认使用的,了解更多可以读这篇文章。
二级缓存:这是在一级缓存之上的缓存,在session factory 范围内有效。
在这篇文章中,我将给出使用ehcache在hibernate配置二级缓存的例子。
这篇文章的结构:
二级缓存是如何工作的
关于ehcache
配置ehcache
配置实体对象
查询缓存
应用例子
源码下载
二级缓存是如何工作的
1、当hibernate Session试着加载实体的时候,会从一级缓存中获取对象的复制(与特定的hibernate Session相关连)
2、如果在一级缓存中存在实体的复制,将会把实体结果返回。
3、如果在一级缓存中不存在缓存的实体,二级缓存会查找是不是有缓存的实体。
4、如果二级缓存中有缓存的实体,将会把实体的结果返回。但是,在返回实体之前,它将会把结果存储到一级缓存中去,下次调用时可以直接从一级缓存中获取相应的结果,这样就没有必要再想二级缓存中获取。
5、如果在一级缓存和二级缓存中都没有找到相应的实体,那么数据库查询语句将会执行,在返回结果之前,实体将会被存储在一二级缓存中。
6、如果通过hibernate操作修改已经完成,对于修改的实体二级缓存会完成相应的验证。
7、如果用户或者进程直接在数据库中做了修改,二级缓存不能更新自己直到timeToLiveSeconds时间结束。在这种情况下最好将所有的缓存失效并让hibernate再一次建立自己的缓存,你可以使用下边的代码片段失效整个hibernate的二级缓存。
2、如果在一级缓存中存在实体的复制,将会把实体结果返回。
3、如果在一级缓存中不存在缓存的实体,二级缓存会查找是不是有缓存的实体。
4、如果二级缓存中有缓存的实体,将会把实体的结果返回。但是,在返回实体之前,它将会把结果存储到一级缓存中去,下次调用时可以直接从一级缓存中获取相应的结果,这样就没有必要再想二级缓存中获取。
5、如果在一级缓存和二级缓存中都没有找到相应的实体,那么数据库查询语句将会执行,在返回结果之前,实体将会被存储在一二级缓存中。
6、如果通过hibernate操作修改已经完成,对于修改的实体二级缓存会完成相应的验证。
7、如果用户或者进程直接在数据库中做了修改,二级缓存不能更新自己直到timeToLiveSeconds时间结束。在这种情况下最好将所有的缓存失效并让hibernate再一次建立自己的缓存,你可以使用下边的代码片段失效整个hibernate的二级缓存。
关于更多二级缓存是如何工作的,可以参考这篇文章。
关于ehcache
Terracotta ehcache是一个流行的开源的Java缓存,可以被用在hibernate的二级缓存中,ehcache也可以被当做独立的二级缓存使用,或者为集群配置提供二级缓存。hibernate可以使用ehcache的库,如果你想要ehcache的某一个具体的版本,可以访问网址
http://www.terracotta.org/products/enterprise-ehcache
ehcache2.0的maven依赖如下:
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>[2.0.0]</version> <type>pom</type></dependency>
配置ehcache
为了配置ehcache,你需要做下边两个步骤的事情:
1、为二级缓存配置hibernate
2、制定二级缓存的提供者
hibernate3.3以上的版本
<property key="hibernate.cache.use_second_level_cache">true</property><property name="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</property>
hibernate3.2和以下版本
<property key="hibernate.cache.use_second_level_cache">true</property><property name="hibernate.cache.region.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property>
配置实体对象
可以使用两种方式
(1)如果使用hbm.xml文件,使用下边的配置
<class name="com.application.entity.DepartmentEntity" table="..."> <cache usage="read-write"/></class>
(2)如果使用注解,是用下边这些注解
@Entity@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,region="department")public class DepartmentEntity implements Serializable{ //code}
对于上边这两种方式,缓存策略可以是下边的类型:
none:不会有缓存发生
read-only:如果你的应用需要读而不是修改,持久类的实例上可以使用read-only缓存
read-write:如果你的缓存需要更新数据,一个read-write缓存是很合适的。
nonstrict-read-write:如果你的应用只在特定的情况下更新数据(例如:一个极特殊的情况,两个事物同时更新数据),并且没有严格是事务独立要求,nonstrict-read-write或许就是合适的选择。
transactional:事务缓存策略为为所有的事务缓存提供者提供支持,比如一个缓存可以仅仅在JTA中使用,你必须指定hibernate.transaction.manager_lookup_class.
查询缓存
你可是使用在hbm.xml中配置如下的语句使查询缓存生效
<property key="hibernate.cache.use_query_cache">true</property>
在你的代码中定义的查询上增加方法setCacheable(true),这样就可以缓存了。
sessionFactory.getCurrentSession().createQuery("...").setCacheable(true).list();
默认情况下,ehcache会为你配置的需要缓存每一个实体划分出不同的缓存区域。你可以在ehcache.xml中增加配置来改变这个默认的区域。
<property name="net.sf.ehcache.configurationResourceName">/ehcache.xml</property>
使用下边的配置覆盖默认的配置
<cache name="com.somecompany.someproject.domain.Country" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"/>
在ehcache.xml中需要注意:如果eternal="true"那么我们不需要写 timeToIdealSeconds, timeToLiveSeconds,hibernate会处理这些值,如果你想人为的给定缓存的值最好还是使用上边的那种配置方式,这样我们就可以手动的将值指定 timeToIdealSeconds,timeToLiveSeconds 。
timeToIdealSeconds=”seconds”意味着,如果对象在全局缓存中是理想的,在全局中使用的类或者对象将会等待超过我们设置的timeToIdealSeconds 时间值将缓存的值删除。
timeToLiveSeconds=”seconds” 意味着,其他的session或者类使用不是使用这个对象,超过这个时间,hibernate将会从全局缓存中将它删除。
例子
在我们的应用例子中,我有一个DepartmentEntity,在这上边使用ehcache的二级缓存,让我们一步一步操作这个事情
1) hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatedemo</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create</property> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping class="hibernate.test.dto.DepartmentEntity"></mapping> </session-factory></hibernate-configuration>
2) DepartmentEntity.java:
package hibernate.test.dto; import java.io.Serializable; import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.UniqueConstraint; import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity (name = "dept")@Table(name = "DEPARTMENT", uniqueConstraints = { @UniqueConstraint(columnNames = "ID"), @UniqueConstraint(columnNames = "NAME") }) @Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="department") public class DepartmentEntity implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID", unique = true, nullable = false) private Integer id; @Column(name = "NAME", unique = true, nullable = false, length = 100) private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
3) HibernateUtil.java:
package hibernate.test; import java.io.File; import org.hibernate.SessionFactory;import org.hibernate.cfg.AnnotationConfiguration; public class HibernateUtil{ private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new AnnotationConfiguration().configure(new File("hibernate.cgf.xml")).buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { // Close caches and connection pools getSessionFactory().close(); }}
4) TestHibernateEhcache.java:
public class TestHibernateEhcache{ public static void main(String[] args) { storeData(); try { //Open the hibernate session Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); //fetch the department entity from database first time DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //fetch the department entity again; Fetched from first level cache department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); //Let's close the session session.getTransaction().commit(); session.close(); //Try to get department in new session Session anotherSession = HibernateUtil.getSessionFactory().openSession(); anotherSession.beginTransaction(); //Here entity is already in second level cache so no database query will be hit department = (DepartmentEntity) anotherSession.load(DepartmentEntity.class, new Integer(1)); System.out.println(department.getName()); anotherSession.getTransaction().commit(); anotherSession.close(); } finally { System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1 System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 1 HibernateUtil.shutdown(); } } private static void storeData() { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); DepartmentEntity department = new DepartmentEntity(); department.setName("Human Resource"); session.save(department); session.getTransaction().commit(); }} Output: Hibernate: insert into DEPARTMENT (NAME) values (?)Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?Human ResourceHuman ResourceHuman Resource11
在上边的输出结果中,我们可以看到,第一次department是从数据库中获取,下边两次是从缓存中获取,最后一次是从二级缓存中获取。
源码下载
0 0
- hibernate ehcache 配置指导
- Hibernate中配置EHCache
- Hibernate+ehcache二级缓存配置
- Hibernate ehcache配置二级缓存
- hibernate之ehcache配置
- Hibernate配置Ehcache二级缓存
- EhCache配置Hibernate二级缓存
- Hibernate+EhCache配置二级缓存
- Spring+Hibernate+EHcache配置
- Spring+Hibernate+EHcache配置
- Hibernate + ehcache配置使用
- Hibernate ehcache配置二级缓存
- Hibernate+EhCache配置二级缓存
- spring + hibernate +ehcache配置
- Hibernate+EHCache配置二级缓存
- hibernate ehcache的配置使用
- Hibernate中配置ehcache案例
- Hibernate中配置ehcache缓存
- 0016.scala中的包
- object-UI之基本控件
- 0017.包、类、对象、成员的访问权限
- 【Leetcode】Populating Next Right Pointers in Each Node
- 传值有四种方法 : 1.属性传值 2.单例传值 3.代理传值 4.block传值
- hibernate ehcache 配置指导
- 传值与传址
- QT显示图片
- Android textAppearance的属性设置及TextView属性详解
- Noip2015总结
- 使用printwhatyoulike打印网页指定内容
- UISearchBar介绍
- [BZOJ2060] [Usaco2010 Nov]Visiting Cows 拜访奶牛
- 收藏——android SDK下载失败和更新方法