MyBatis-24MyBatis缓存配置【集成EhCache】
文章目錄
- 概述
- EhCache概述
- 特點
- EhCache架構圖
- 示例
- 1.添加mybatis-ehcache依賴
- 2. 配置EhCache
- 3.修改PrivilegeMapper.xml中的緩存配置
- 4.單元測試
概述
Spring Cache抽象-基于XML的配置聲明(基于EhCache的配置)
Spring Cache抽象-使用Java類注解的方式整合EhCache
EhCache概述
官方網站: http://www.ehcache.org/
Ehcache是一個用Java實現的使用簡單,高速,實現線程安全的緩存管理類庫,ehcache提供了用內存,磁盤文件存儲,以及分布式存儲方式等多種靈活的cache管理方案。
Ehcache 從 Hibernate 發展而來,逐漸涵蓋了 Cahce 界的全部功能,是目前發展勢頭最好的一個項目。具有快速,簡單,低消耗,依賴性小,擴展性強,支持對象或序列化緩存,支持緩存或元素的失效,提供 LRU、LFU 和 FIFO 緩存策略,支持內存緩存和磁盤緩存,分布式緩存機制等等特點。
特點
- 快速
- 簡單
- 多種緩存策略
- 緩存數據有兩級:內存和磁盤,因此無需擔心容量問題
- 緩存數據會在虛擬機重啟的過程中寫入磁盤
- 可以通過 RMI、可插入 API 等方式進行分布式緩存
- 具有緩存和緩存管理器的偵聽接口
- 支持多緩存管理器實例,以及一個實例的多個緩存區域
- 提供 Hibernate 的緩存實現
EhCache架構圖
-
CacheManager:是緩存管理器,可以通過單例或者多例的方式創建,Ehcache的入口類。
-
Cache:每個CacheManager可以管理多個Cache,每個Cache可以采用hash的方式管理多個Element。
-
Element:用于存放真正緩存內容的。
示例
1.添加mybatis-ehcache依賴
<properties>.....<mybatis-ehcache.version>1.0.3</mybatis-ehcache.version> </properties><dependencies>......<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>${mybatis-ehcache.version}</version></dependency> </dependencies>2. 配置EhCache
在src/main/resources 目錄下 新建ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd"updateCheck="false" monitoring="autodetect"dynamicConfig="true"><diskStore path="D:/cache" /><defaultCache maxElementsInMemory="3000" eternal="false" copyOnRead="true"copyOnWrite="true"timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="true" diskPersistent="true"/> </ehcache>關于EhCache配置文件參考官網配置
http://www.ehcache.org/ehcache.xml
屬性解讀
copyOnRead:判斷從緩存中讀取數據時是返回對象的引用還是復制一個對象返回。 默認false,即返回數據的引用。 這種情況下返回的都是相同的對象,和MyBatis默認緩存中的只讀對象是相同的。 如果設置為true,那就是可讀可寫緩存,每次讀取緩存都會復制一個新的實例
copyOnWrite:判斷寫入緩存時是直接緩存對象的引用還是復制一個對象然后緩存。 默認也是false。如果想使用可讀可寫緩存,就需要將這兩個屬性配置為true。 如果使用只讀緩存,可以不配置這兩個屬性,使用默認false即可。
3.修改PrivilegeMapper.xml中的緩存配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><!-- 當Mapper接口和XML文件關聯的時候, namespace的值就需要配置成接口的全限定名稱 --> <mapper namespace="com.artisan.mybatis.xml.mapper.PrivilegeMapper"><!-- 在全局配置文件開啟二級緩存的前提下,給Privilege開啟二級緩存,使用默認配置<cache/>--><!-- 集成EhCache緩存 --><cache type="org.mybatis.caches.ehcache.EhcacheCache"/><resultMap id="privilegeMap" type="com.artisan.mybatis.xml.domain.SysPrivilege"><id property="id" column="id" /><result property="privilegeName" column="privilege_name" /><result property="privilegeUrl" column="privilege_url" /></resultMap><select id="selectPrivilegeByIdWithCache" resultType="com.artisan.mybatis.xml.domain.SysPrivilege">SELECTid,privilege_name privilegeName,privilege_url privilegeUrlFROMsys_privilegeWHEREid = #{id}</select></mapper>e h c a c h e - c a c h e提供如下2個可選的緩存實現
并沒有什么區別,都會輸出緩存命中率的日志
只需要設置type屬性就可以使用EhCache緩存了,這時候cache的其他屬性都不會起作用,這對緩存的配置都在ehcache.xml中進行。
在ehcache.xml中只有一個默認的緩存配置,所以配置使用EhCache緩存的Mapper映射文件都會有一個以映射文件命令空間命名的緩存。 如果想針對某一個命名空間配置,需要在ehcache.xml中添加一個和映射文件命名空間一致的緩存配置。比如針對PrivilegeMapper
<cache name="com.artisan.mybatis.xml.mapper.PrivilegeMapper"maxElementsInMemory="3000" eternal="false" copyOnRead="true"copyOnWrite="true"timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="true" diskPersistent="true"/>4.單元測試
@Testpublic void selectPrivilegeByIdWithCacheTest() {logger.info("selectPrivilegeByIdWithCacheTest");SqlSession sqlSession = getSqlSession();SysPrivilege sysPrivilege = null;try {// 獲取接口PrivilegeMapper privilegeMapper = sqlSession.getMapper(PrivilegeMapper.class);// 調用接口方法sysPrivilege = privilegeMapper.selectPrivilegeByIdWithCache(1L);sysPrivilege.setPrivilegeName("New Priv");// 再次調用相同的接口方法,查詢相同的用戶logger.info("再次調用相同的接口方法,查詢相同的用戶 Begin");SysPrivilege sysPrivilege2 = privilegeMapper.selectPrivilegeByIdWithCache(1L);logger.info("再次調用相同的接口方法,查詢相同的用戶 End");// 一級緩存在同一個sqlSession中,雖然沒有更新數據庫,但是會使用一級緩存Assert.assertEquals("New Priv", sysPrivilege2.getPrivilegeName());// sysPrivilege 和 sysPrivilege2 是同一個實例Assert.assertEquals(sysPrivilege, sysPrivilege2);} finally {// sqlSession關閉后,在二級緩存開啟的前提下,會寫入二級緩存sqlSession.close();}logger.info("重新獲取一個SqlSession");sqlSession = getSqlSession();try {// 獲取接口PrivilegeMapper privilegeMapper = sqlSession.getMapper(PrivilegeMapper.class);// 調用接口方法SysPrivilege sysPrivilege2 = privilegeMapper.selectPrivilegeByIdWithCache(1L);sysPrivilege.setPrivilegeName("New Priv");// 第二個session獲取的權限名為 New PrivAssert.assertEquals("New Priv", sysPrivilege2.getPrivilegeName());// 這里的sysPrivilege2 和 前一個session中的sysPrivilege不是同一個實例Assert.assertNotEquals(sysPrivilege, sysPrivilege2);// 獲取sysPrivilege3SysPrivilege sysPrivilege3 = privilegeMapper.selectPrivilegeByIdWithCache(1L);// 這里的sysPrivilege2 和sysPrivilege3是兩個不同的實例Assert.assertNotEquals(sysPrivilege2, sysPrivilege3);} finally {// sqlSession關閉后,在二級緩存開啟的前提下,會寫入二級緩存sqlSession.close();}}日志
2018-05-07 19:58:27,653 INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully 2018-05-07 19:58:27,656 INFO [main] (BaseMapperTest.java:29) - reader close successfully 2018-05-07 19:58:27,659 INFO [main] (PrivilegeMapperTest.java:38) - selectPrivilegeByIdWithCacheTest 2018-05-07 19:58:27,682 DEBUG [main] (LoggingCache.java:62) - Cache Hit Ratio [com.artisan.mybatis.xml.mapper.PrivilegeMapper]: 0.0 2018-05-07 19:58:27,743 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Preparing: SELECT id, privilege_name privilegeName, privilege_url privilegeUrl FROM sys_privilege WHERE id = ? 2018-05-07 19:58:27,855 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters: 1(Long) 2018-05-07 19:58:27,886 TRACE [main] (BaseJdbcLogger.java:151) - <== Columns: id, privilegeName, privilegeUrl 2018-05-07 19:58:27,887 TRACE [main] (BaseJdbcLogger.java:151) - <== Row: 1, 用戶管理, /users 2018-05-07 19:58:27,890 DEBUG [main] (BaseJdbcLogger.java:145) - <== Total: 1 2018-05-07 19:58:27,892 INFO [main] (PrivilegeMapperTest.java:48) - 再次調用相同的接口方法,查詢相同的用戶 Begin 2018-05-07 19:58:27,892 DEBUG [main] (LoggingCache.java:62) - Cache Hit Ratio [com.artisan.mybatis.xml.mapper.PrivilegeMapper]: 0.0 2018-05-07 19:58:27,893 INFO [main] (PrivilegeMapperTest.java:50) - 再次調用相同的接口方法,查詢相同的用戶 End 2018-05-07 19:58:27,923 INFO [main] (PrivilegeMapperTest.java:60) - 重新獲取一個SqlSession 2018-05-07 19:58:27,927 DEBUG [main] (LoggingCache.java:62) - Cache Hit Ratio [com.artisan.mybatis.xml.mapper.PrivilegeMapper]: 0.3333333333333333 2018-05-07 19:58:27,928 DEBUG [main] (LoggingCache.java:62) - Cache Hit Ratio [com.artisan.mybatis.xml.mapper.PrivilegeMapper]: 0.5總結
以上是生活随笔為你收集整理的MyBatis-24MyBatis缓存配置【集成EhCache】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis-23MyBatis缓存配
- 下一篇: MyBatis-25MyBatis缓存配