(12) Hibernate+EhCache配置二级缓存
轉載地址 http://jyao.iteye.com/blog/1315726
(有關EhCache的基礎介紹可參見:http://sjsky.iteye.com/blog/1288257?)
本文主要講一講Hibernate+EhCache配置二級緩存的基本使用方法,主要分以下兩個方面介紹:
一Cache的多種配置方法
二Hibernate+EhCache集成demo
[一]、Cache的多種配置方法
Javabean cache的配置有三種,下面將一一介紹,具體如下::
(1).bean中注解配置的方式:@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
(2).hibernate.cfg.xml中標簽配置方式:<class-cache class="" usage="" />
(3).映射文件*.hb.xml中標簽配置方式:<cache usage=" />
classpath:ehcahce.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <diskStore path="java.io.tmpdir"/> <transactionManagerLookup class="net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup" properties="jndiName=java:/TransactionManager" propertySeparator=";"/> <cacheManagerEventListenerFactory class="" properties=""/> <defaultCache maxElementsInMemory="100" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="100" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="false" /> <cache name="org.hibernate.cache.StandardQueryCache" maxElementsInMemory="5" eternal="false" timeToLiveSeconds="120" overflowToDisk="true" /> <cache name="org.hibernate.cache.UpdateTimestampsCache" maxElementsInMemory="5000" eternal="true" overflowToDisk="true" /> <cache name="sampleCache1" maxElementsInMemory="10000" maxElementsOnDisk="1000" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" transactionalMode="off" /> <cache name="sampleCache2" maxElementsInMemory="1000" eternal="true" overflowToDisk="false" memoryStoreEvictionPolicy="FIFO" /> </ehcache>2 hibernate配置文件:hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver </property> <property name="connection.url"> jdbc:oracle:thin:@localhost:1521:ora11g </property> <property name="connection.username">mytest</property> <property name="connection.password">111111</property> <property name="dialect"> org.hibernate.dialect.Oracle9Dialect </property> <property name="connection.useUnicode">true</property> <property name="connection.characterEncoding">UTF-8</property> <property name="connection.SetBigStringTryClob">true</property> <property name="connection.pool_size">10</property> <property name="hibernate.jdbc.batch_size">10</property> <property name="show_sql">true</property> <property name="format_sql">false</property> <property name="current_session_context_class">thread</property> <property name="hbm2ddl.auto">update</property> <!-- Hibernate 3.3 and higher --> <!-- <property name="hibernate.cache.region.factory_class"> net.sf.ehcache.hibernate.EhCacheRegionFactory </property> <property name="hibernate.cache.region.factory_class"> net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory </property> --> <!-- hibernate3.0-3.2 cache config--> <!-- <property name="hibernate.cache.region.factory_class"> net.sf.ehcache.hibernate.EhCacheProvider </property> --> <property name="hibernate.cache.provider_class"> net.sf.ehcache.hibernate.SingletonEhCacheProvider </property> <!-- Enable Second-Level Cache and Query Cache Settings --> <property name="hibernate.cache.use_second_level_cache"> true </property> <property name="hibernate.cache.use_query_cache"> true </property> <!-- 注解配置 --> <mapping class="michael.cache.ehcache.hibernate.EhUserInfo" /> <mapping class="michael.cache.ehcache.hibernate.EhBlogTopic" /> <mapping class="michael.cache.ehcache.hibernate.EhBlogTopic2" /> <!-- 映射文件 --> <mapping resource="michael/cache/ehcache/hibernate/tb_EhBlogTopic3.hb.xml" /> <!-- class-cache config --> <class-cache class="michael.cache.ehcache.hibernate.EhBlogTopic" usage="read-write" /> </session-factory> </hibernate-configuration>3.相關javabean代碼片段如下:
(1).hibernate.cfg.xml中<calss-cache>標簽配置的:EhBlogTopic.java:
/** * @blog http://sjsky.iteye.com * @author Michael */ @Entity @Table(name = "MY_TB_EH_BLOG_TOPIC") public class EhBlogTopic implements Serializable { /** * serialVersionUID */ private static final long serialVersionUID = -570936907944909799L; private Integer id; private String userId; private String topic; private String site; //其他省略 }(2). bean中注解的方式配置cache的:EhBlogTopic2.java
/** * @blog http://sjsky.iteye.com * @author Michael */ @Entity @Table(name = "MY_TB_EH_BLOG_TOPIC2") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class EhBlogTopic2 implements Serializable { //屬性和EhBlogTopic一樣 //其他省略 } . 映射文件*.hb.xml中添加cache標簽的: EhBlogTopic3.java /** * @blog http://sjsky.iteye.com * @author Michael */ public class EhBlogTopic3 implements Serializable { //屬性和EhBlogTopic一樣 //其他省略 }(3). 映射文件*.hb.xml中添加cache標簽的:EhBlogTopic3.java
/***@blog http://sjsky.iteye.com*@author Michael*/ public class EhBlogTopic3 implementsSerializable { //屬性和EhBlogTopic一樣 //其他省略 }?tb_EhBlogTopic3.hb.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="michael.cache.ehcache.hibernate"> <class name="EhBlogTopic3" table="MY_TB_EH_BLOG_TOPIC3"> <cache usage="read-write" /> <id name="id" type="int" unsaved-value="null"> <generator class="increment" /> </id> <property name="userId" column="USER_ID" type="string" not-null="false" length="20" /> <property name="topic" column="TOPIC" type="string" not-null="false" length="100" /> <property name="site" column="SITE" type="string" not-null="false" length="100" /> </class> </hibernate-mapping>沒有配置cache的bean:EhUserInfo.java
/** * @blog http://sjsky.iteye.com * @author Michael */ @Entity @Table(name = "MY_TB_EH_USER_INFO") public class EhUserInfo implements Serializable { /** * serialVersionUID */ private static final long serialVersionUID = 930384253681679239L; private Integer id; private String userId; private String userName; private String otherInfo; /** * @return the id */ @Id @GeneratedValue @Column(name = "ID") public Integer getId() { return id; } //其他省略。。。 }4.測試運行代碼如下:
package michael.cache.ehcache.hibernate; import java.util.List; import michael.hibernate.bigstring.oracle.BigStrBlob; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.cfg.Configuration; /** * * @blog http://sjsky.iteye.com * @author Michael */ public class TestEhcacheHibernate { /** * @param args */ @SuppressWarnings("unchecked") public static void main(String[] args) { testMulitConfigMethod(); } /** * 測試多種配置緩存的方法 */ public static void testMulitConfigMethod() { SessionFactory sessionFactory = null; try { System.out.println("ehcache - hibernate Test ..."); Configuration config = new AnnotationConfiguration() .configure("michael/cache/ehcache/hibernate/hibernate.cfg.xml"); System.out.println("hibernate config successful :" + config); sessionFactory = config.buildSessionFactory(); Transaction ta = null; try { Session session = sessionFactory.getCurrentSession(); ta = session.beginTransaction(); } catch (Exception e) { e.printStackTrace(); ta.rollback(); } String[] cacheNames = CacheManager.getInstance().getCacheNames(); System.out.println("緩存的key cacheNames length := " + cacheNames.length + " 具體詳細列表如下:"); for (String name : cacheNames) { System.out.println("name := " + name); } } catch (Exception e) { e.printStackTrace(); } System.out.println("ehcache - hibernate Test end."); } }運行結果如下:
ehcache - hibernate Test ... hibernate config successful :org.hibernate.cfg.AnnotationConfiguration@193c0cf 2011-12-15 11:32:36 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache 警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic]; using defaults. 2011-12-15 11:32:36 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache 警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic2]; using defaults. 2011-12-15 11:32:36 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache 警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic3]; using defaults. 2011-12-15 11:32:37 net.sf.ehcache.util.UpdateChecker doCheck 信息: New update(s) found: 2.4.6 [http://www.terracotta.org/confluence/display/release/Release+Notes+Ehcache+Core+2.4]. Please check http://ehcache.org for the latest version. 緩存的key cacheNames length := 7 具體詳細列表如下: name := sampleCache2 name := michael.cache.ehcache.hibernate.EhBlogTopic2 name := org.hibernate.cache.UpdateTimestampsCache name := sampleCache1 name := michael.cache.ehcache.hibernate.EhBlogTopic name := org.hibernate.cache.StandardQueryCache name := michael.cache.ehcache.hibernate.EhBlogTopic3 ehcache - hibernate Test end.
從運行結果可見:三種方式的緩存配置都已經成功。
[二]、Hibernate+EhCache集成demo
?1.分別初始化EhUserInfo(沒有配置cache的)和EhBlogTopic(配置過cache的)數據如下:
EhUserInfo:
EhBlogTopic:?
?2.演示代碼:
package michael.cache.ehcache.hibernate; import java.util.List; import michael.hibernate.bigstring.oracle.BigStrBlob; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.cfg.Configuration; /** * * @blog http://sjsky.iteye.com * @author Michael */ public class TestEhcacheHibernate { /** * @param args */ @SuppressWarnings("unchecked") public static void main(String[] args) { SessionFactory sessionFactory = null; try { System.out.println("ehcache - hibernate Test ..."); Configuration config = new AnnotationConfiguration() .configure("michael/cache/ehcache/hibernate/hibernate.cfg.xml"); sessionFactory = config.buildSessionFactory(); System.out.println("buildSessionFactory==============="); System.out.println("===================================="); System.out.println("session open ...."); System.out.println("同一個session(一級緩存默認的)中,沒有配置cache的Bean"); Transaction ta = null; try { Session session = sessionFactory.getCurrentSession(); String hsql = "select t from EhUserInfo t "; ta = session.beginTransaction(); Query query = session.createQuery(hsql); System.out.println("查詢全部query.list().size:" + query.list().size()); System.out.println("再根據ID=1查詢某記錄時不會再去查數據庫,故不會打印hsql"); EhUserInfo vo1 = (EhUserInfo) session.get(EhUserInfo.class, 1); System.out.println("根據ID=1找到的記錄:" + vo1); ta.commit(); } catch (Exception e) { e.printStackTrace(); ta.rollback(); } System.out.println("session closed."); System.out.println("session open ...."); try { Session session = sessionFactory.getCurrentSession(); ta = session.beginTransaction(); System.out.println("第一次根據ID=1查詢某記錄時,會打印hsql"); EhUserInfo vo1 = (EhUserInfo) session.get(EhUserInfo.class, 1); System.out.println("根據ID=1找到的記錄:" + vo1); ta.commit(); } catch (Exception e) { e.printStackTrace(); ta.rollback(); } System.out.println("session closed."); System.out.println("===================================="); System.out.println("當前同一個sessionFactory,沒有配置cache的Bean,"); System.out.println("session open ...."); try { Session session = sessionFactory.getCurrentSession(); ta = session.beginTransaction(); System.out.println("第一次根據ID=1查詢記錄時會再去查數據庫,故打印hsql如下:"); EhUserInfo vo1 = (EhUserInfo) session.get(EhUserInfo.class, 1); System.out.println("根據ID=1找到的記錄:" + vo1); ta.commit(); } catch (Exception e) { e.printStackTrace(); ta.rollback(); } System.out.println("session closed."); System.out.println("===================================="); String[] cacheNames = CacheManager.getInstance().getCacheNames(); System.out.println("緩存的key cacheNames length := " + cacheNames.length); for (String name : cacheNames) { System.out.println("name := " + name); } System.out.println("===================================="); System.out.println("同一個session(一級緩存默認的)中,配置cache的Bean"); System.out.println("session open ...."); try { Session session = sessionFactory.getCurrentSession(); String hsql = "select t from EhBlogTopic t "; ta = session.beginTransaction(); Query query = session.createQuery(hsql); query.setCacheable(true); System.out.println("查詢全部query.list().size:" + query.list().size()); Cache myCache1 = CacheManager.getInstance().getCache( "michael.cache.ehcache.hibernate.EhBlogTopic"); System.out.println("查詢到EhBlogTopic cache size:" + myCache1.getKeys().size()); myCache1 = CacheManager.getInstance().getCache( "michael.cache.ehcache.hibernate.EhBlogTopic"); System.out.println("EhBlogTopic cache size:" + myCache1.getKeys().size() + ",詳細記錄如下:"); for (Object str : myCache1.getKeys()) { System.out.println(str); } System.out .println("在同一個session,再根據ID=1查詢記錄時不會再去查數據庫,故不會打印hsql"); EhBlogTopic vo1 = (EhBlogTopic) session.get(EhBlogTopic.class, 1); System.out.println("根據ID=1找到的記錄:" + vo1); EhBlogTopic vo2 = new EhBlogTopic(); vo2.setId(10); vo2.setUserId("michael"); vo2.setTopic("Myblog:11"); vo2.setSite("http://sjsky.iteye.com"); session.save(vo2); ta.commit(); System.out.println("新增加一條記錄ID=10"); } catch (Exception e) { e.printStackTrace(); ta.rollback(); } System.out.println("session closed."); System.out.println("===================================="); Cache myCache1 = CacheManager.getInstance().getCache( "michael.cache.ehcache.hibernate.EhBlogTopic"); System.out.println("EhBlogTopic cache size:" + myCache1.getKeys().size() + ",詳細記錄如下:"); for (Object str : myCache1.getKeys()) { System.out.println(str); } System.out.println("===================================="); System.out.println("在當前同一個sessionFactory,配置cache的bean"); System.out.println("session open ...."); try { Session session = sessionFactory.getCurrentSession(); ta = session.beginTransaction(); System.out .println("不管是否第一次查詢ID=1的記錄,如果cache中存在的,則不會再查數據庫,故不打印hsql"); EhBlogTopic vo1 = (EhBlogTopic) session.get(EhBlogTopic.class, 1); System.out.println("根據ID=1找到的記錄:" + vo1); System.out.println("查詢之前session保存的數據ID=10,也不會再查數據庫,故不打印hsql"); EhBlogTopic vo2 = (EhBlogTopic) session.get(EhBlogTopic.class, 10); System.out.println("根據之前save的ID=10找到的記錄:" + vo2); ta.commit(); } catch (Exception e) { e.printStackTrace(); ta.rollback(); } System.out.println("session closed."); } catch (Exception e) { e.printStackTrace(); } finally { if (null != sessionFactory) { sessionFactory.close(); } } System.out.println("sessionFactory closed."); } }運行結果如下:
ehcache - hibernate Test ... 2011-12-15 13:27:15 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache 警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic]; using defaults. 2011-12-15 13:27:15 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache 警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic2]; using defaults. 2011-12-15 13:27:15 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache 警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic3]; using defaults. buildSessionFactory=============== ==================================== session open .... 同一個session(一級緩存默認的)中,沒有配置cache的Bean Hibernate: select ehuserinfo0_.ID as ID1_, ehuserinfo0_.USER_ID as USER2_1_, ehuserinfo0_.USER_NAME as USER3_1_, ehuserinfo0_.OHTER_INFO as OHTER4_1_ from MY_TB_EH_USER_INFO ehuserinfo0_ 查詢全部query.list().size:2 再根據ID=1查詢某記錄時不會再去查數據庫,故不會打印hsql 根據ID=1找到的記錄:michael.cache.ehcache.hibernate.EhUserInfo@63b2e6 session closed. session open .... 第一次根據ID=1查詢某記錄時,會打印hsql Hibernate: select ehuserinfo0_.ID as ID1_0_, ehuserinfo0_.USER_ID as USER2_1_0_, ehuserinfo0_.USER_NAME as USER3_1_0_, ehuserinfo0_.OHTER_INFO as OHTER4_1_0_ from MY_TB_EH_USER_INFO ehuserinfo0_ where ehuserinfo0_.ID=? 根據ID=1找到的記錄:michael.cache.ehcache.hibernate.EhUserInfo@123a389 session closed. ==================================== 當前同一個sessionFactory,沒有配置cache的Bean, session open .... 第一次根據ID=1查詢記錄時會再去查數據庫,故打印hsql如下: Hibernate: select ehuserinfo0_.ID as ID1_0_, ehuserinfo0_.USER_ID as USER2_1_0_, ehuserinfo0_.USER_NAME as USER3_1_0_, ehuserinfo0_.OHTER_INFO as OHTER4_1_0_ from MY_TB_EH_USER_INFO ehuserinfo0_ where ehuserinfo0_.ID=? 根據ID=1找到的記錄:michael.cache.ehcache.hibernate.EhUserInfo@429c19 session closed. ==================================== 緩存的key cacheNames length := 7 name := sampleCache2 name := michael.cache.ehcache.hibernate.EhBlogTopic2 name := org.hibernate.cache.UpdateTimestampsCache name := sampleCache1 name := michael.cache.ehcache.hibernate.EhBlogTopic name := org.hibernate.cache.StandardQueryCache name := michael.cache.ehcache.hibernate.EhBlogTopic3 ==================================== 同一個session(一級緩存默認的)中,配置cache的Bean session open .... Hibernate: select ehblogtopi0_.ID as ID2_, ehblogtopi0_.USER_ID as USER2_2_, ehblogtopi0_.TOPIC as TOPIC2_, ehblogtopi0_.SITE as SITE2_ from MY_TB_EH_BLOG_TOPIC ehblogtopi0_ 查詢全部query.list().size:9 查詢到EhBlogTopic cache size:9 EhBlogTopic cache size:9,詳細記錄如下: michael.cache.ehcache.hibernate.EhBlogTopic#6 michael.cache.ehcache.hibernate.EhBlogTopic#5 michael.cache.ehcache.hibernate.EhBlogTopic#7 michael.cache.ehcache.hibernate.EhBlogTopic#8 michael.cache.ehcache.hibernate.EhBlogTopic#2 michael.cache.ehcache.hibernate.EhBlogTopic#9 michael.cache.ehcache.hibernate.EhBlogTopic#1 michael.cache.ehcache.hibernate.EhBlogTopic#4 michael.cache.ehcache.hibernate.EhBlogTopic#3 在同一個session,再根據ID=1查詢記錄時不會再去查數據庫,故不會打印hsql 根據ID=1找到的記錄:michael.cache.ehcache.hibernate.EhBlogTopic@11a0d35 Hibernate: insert into MY_TB_EH_BLOG_TOPIC (USER_ID, TOPIC, SITE, ID) values (?, ?, ?, ?) 新增加一條記錄ID=10 session closed. ==================================== EhBlogTopic cache size:10,詳細記錄如下: michael.cache.ehcache.hibernate.EhBlogTopic#6 michael.cache.ehcache.hibernate.EhBlogTopic#5 michael.cache.ehcache.hibernate.EhBlogTopic#7 michael.cache.ehcache.hibernate.EhBlogTopic#8 michael.cache.ehcache.hibernate.EhBlogTopic#2 michael.cache.ehcache.hibernate.EhBlogTopic#9 michael.cache.ehcache.hibernate.EhBlogTopic#10 michael.cache.ehcache.hibernate.EhBlogTopic#1 michael.cache.ehcache.hibernate.EhBlogTopic#4 michael.cache.ehcache.hibernate.EhBlogTopic#3 ==================================== 在當前同一個sessionFactory,配置cache的bean session open .... 不管是否第一次查詢ID=1的記錄,如果cache中存在的,則不會再查數據庫,故不打印hsql 根據ID=1找到的記錄:michael.cache.ehcache.hibernate.EhBlogTopic@1321f5 查詢之前session保存的數據ID=10,也不會再查數據庫,故不打印hsql 根據之前save的ID=10找到的記錄:michael.cache.ehcache.hibernate.EhBlogTopic@1a6518 session closed. sessionFactory closed.我們從上面的詳細運行日志中就可以看出cache的效果。
總結
以上是生活随笔為你收集整理的(12) Hibernate+EhCache配置二级缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (11) Hibernate 缓存机制
- 下一篇: js控制table中tr位置互换