hibernate4 二级缓存demo实例
hibernate使用版本是:hibernate-release-4.2.5.Final
需要的jar包:hibernate-release-4.2.5.Final\lib\required下所有jar包
ehcache? jar包:hibernate-release-4.2.5.Final\lib\optional\ehcache下所有包
junit:junit-4.10.jar和mysql-connector-java-5.1.15-bin.jar
注:hibernate 4.2.5版本ehcache缓存不依赖commons-logging-1.1.1.jar,需要的是slf4j-api-1.6.1.jar
项目结构如下
?
?
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><!-- Database connection settings --><property name="connection.driver_class">com.mysql.jdbc.Driver</property><property name="connection.url">jdbc:mysql://127.0.0.1:3306/hibernate4</property><property name="connection.username">root</property><property name="connection.password">root</property><!-- JDBC connection pool (use the built-in) --><property name="connection.pool_size">1</property><!-- SQL dialect --><property name="dialect">org.hibernate.dialect.MySQL5Dialect</property><!-- Enable Hibernate's automatic session context management --><property name="current_session_context_class">thread</property><!-- Disable the second-level cache --><!--<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>--><!-- 配置二级缓存 --><property name="hibernate.cache.use_second_level_cache">true</property><property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property><!-- hibernate3的二级缓存配置 --><!-- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> --><!-- 开启查询缓存 --><property name="hibernate.cache.use_query_cache">true</property><!-- Echo all executed SQL to stdout --><property name="show_sql">true</property><!-- Drop and re-create the database schema on startup --><property name="hbm2ddl.auto">update</property><mapping /></session-factory></hibernate-configuration>
?
注意:hibernate4和hibernate3配置不一样,hibernate4是
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
?
而hibernate3的配置是
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
?此处有一个疑问是:hibernate4的官方文档中,已经把class改了,但是属性名称没有改,还是hibernate.cache.provider_class,不是上面的hibernate.cache.region.factory_class,但是写成hibernate.cache.provider_class会报下面错误
?
org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:186)at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:150)at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:264)at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1790)at com.test.pojo.UserTest.beforeClass(UserTest.java:28)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)at org.junit.runners.ParentRunner.run(ParentRunner.java:300)at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)Caused by: org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given, please either disable second level cache or set correct region factory class name to property hibernate.cache.region.factory_class (and make sure the second level cache provider, hibernate-infinispan, for example, is available in the classpath).at org.hibernate.cache.internal.NoCachingRegionFactory.buildTimestampsRegion(NoCachingRegionFactory.java:87)at org.hibernate.cache.spi.UpdateTimestampsCache.<init>(UpdateTimestampsCache.java:62)at org.hibernate.internal.CacheImpl.<init>(CacheImpl.java:72)at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:40)at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:35)at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:91)at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:176)... 20 more
?说是hibernate.cache.region.factory_class属性没有配置,估计官方文档里没有把属性改过来。。。
?
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"updateCheck="false"><!--name:cache唯一标识 eternal:缓存是否永久有效 maxElementsInMemory:内存中最大缓存对象数overflowToDisk(true,false):缓存对象达到最大数后,将缓存写到硬盘中diskPersistent:硬盘持久化timeToIdleSeconds:缓存清除时间 timeToLiveSeconds:缓存存活时间memoryStoreEvictionPolicy:缓存清空策略1.FIFO:first in first out 先讲先出2.LFU: Less Frequently Used 一直以来最少被使用的3.LRU:Least Recently Used 最近最少使用的--><defaultCache maxElementsInMemory="1000" eternal="false"timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /><cache name="userCache" eternal="false" maxElementsInMemory="1000"overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="3600"timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU" /></ehcache>
?
User实体类
package com.test.pojo;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy;@Entity@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)public class User {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)private int id;private String name;private int age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
?
UserTest测试类:
package com.test.pojo;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.BeforeClass;import org.junit.Test;public class UserTest {private static SessionFactory sessionFactory = null;@BeforeClasspublic static void beforeClass() {Configuration configuration = new Configuration();try {configuration.configure();} catch (HibernateException e) {// TODO Auto-generated catch blocke.printStackTrace();}ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);} @Testpublic void testEhcache() {Session session = sessionFactory.openSession();session.beginTransaction();User u1 = (User) session.load(User.class, 3);System.out.println(u1.getName());session.getTransaction().commit();session.close();Session session2 = sessionFactory.openSession();session2.beginTransaction();User u2 = (User) session2.load(User.class, 3);System.out.println(u2.getName());session2.getTransaction().commit();session2.close();}}
?结果:
Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_ from User user0_ where user0_.id=?zhangsanzhangsan
?
list二级缓存测试
package com.test.pojo;import java.util.List;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.BeforeClass;import org.junit.Test;public class UserTest {private static SessionFactory sessionFactory = null;@BeforeClasspublic static void beforeClass() {Configuration configuration = new Configuration();try {configuration.configure();} catch (HibernateException e) {// TODO Auto-generated catch blocke.printStackTrace();}ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);} @SuppressWarnings("unchecked")@Testpublic void testListEhcache() {Session session = sessionFactory.openSession();session.beginTransaction();List<User> users1 = (List<User>)session.createQuery("from User").setCacheable(true).list();for(User user : users1) {System.out.println(user.getName());}session.getTransaction().commit();session.close();Session session2 = sessionFactory.openSession();session2.beginTransaction();List<User> users2 = (List<User>)session2.createQuery("from User").setCacheable(true).list();for(User user : users2) {System.out.println(user.getName());}session2.getTransaction().commit();session2.close();}}
?输出结果:
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from User user0_zhangsanzhangsanlisiwangwuzhangsanzhangsanlisiwangwu
?
?