本文主要讲一讲Hibernate+EhCache配置二级缓存的基本使用方法,主要分以下两个方面介绍:
(有关EhCache的基础介绍可参见:http://www.micmiu.com/architecture/cache/ehcache-start-demo/)
- 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=” />
1. 配置文件 classpath:ehcahce.xml如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<!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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/** * @blog http://www.micmiu.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
1 2 3 4 5 6 7 8 9 10 11 |
/** * @blog http://www.micmiu.com * @author Michael */ @Entity @Table(name = "MY_TB_EH_BLOG_TOPIC2") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class EhBlogTopic2 implements Serializable { //属性和EhBlogTopic一样 //其他省略 } |
(3). 映射文件*.hb.xml中添加cache标签的: EhBlogTopic3.java
1 2 3 4 5 6 7 8 |
/** * @blog http://www.micmiu.com * @author Michael */ public class EhBlogTopic3 implements Serializable { //属性和EhBlogTopic一样 //其他省略 } |
tb_EhBlogTopic3.hb.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?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> |
(4). 没有配置cache的bean: EhUserInfo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/** * @blog http://www.micmiu.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.测试运行代码如下:
TestEhcacheHibernate.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
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://www.micmiu.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:
2.演示代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
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://www.micmiu.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的效果。
原创文章,转载请注明: 转载自micmiu – 软件开发+生活点滴[ http://www.micmiu.com/ ]
本文链接地址: http://www.micmiu.com/j2ee/hibernate/hibernate-ehcache-demo/
0 条评论。