mybatis集成ehcache

前言-Mybatis整合第三方缓存原理图:

image
解读:

  • 客户从数据库获取数据视为一次会话,抽象为sqlSession对象
  • 一个Excutor包含增删改查的操作;
  • CachingExcutor是对Excutor的包装,此处相当于代理模式
  • 当有会话时,先访问CachingExcutor对象,CachingExcutor先从二级缓存查找数据,如果有就直接返回;如果没有,就进入Excutor的一级缓存,如果还是没有就执行Excutor的增删改查返回结果,并将结果保存至缓存中,同一个sqlSession再次访问就可以从一级缓存中取了;
  • 由于mybatis的缓存只用了map实现,所以mybatis允许缓存由第三方缓存来实现,并定义了cache接口,第三方只要实现该接口即可,和mybatis整合在一起后由mybatis在程序中进行调用;

1、导入ehcache依赖

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.6.8</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.3</version>
</dependency>

2、开启二级缓存

<setting name="cacheEnabled" value="true"/>

3、在resources添加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">

    <!--<diskStore path="./tmpdir/Tmp_EhCache"/>-->
    <!--<diskStore path="D:55ehcache" />-->
    <!-- 磁盘保存路径 -->
    <diskStore path="D:441ehcache" />

    <defaultCache
            maxElementsInMemory="1"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
</ehcache>
<!-- 
属性说明:
l diskStore:当内存中不够存储时,存储到指定数据在磁盘中的存储位置。
l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略

以下属性是必须的:
l maxElementsInMemory - 在内存中缓存的element的最大数目 
l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
l overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上

以下属性是可选的:
l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
l timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
 -->

4、pojo类实现Serializable

5、mapper引入二级缓存标签

image

6、测试效果

@Test
public void test(){
   SqlSession sqlSession = MybatisUtils.getSqlSession();
   SqlSession sqlSession2 = MybatisUtils.getSqlSession();
   UserMapper mapper = sqlSession.getMapper(UserMapper.class);
   User user = mapper.getUserById(1);
   System.out.println(user);
   MybatisUtils.closeSqlSession(sqlSession);

   System.out.println("================================");
   UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
   User user2 = mapper2.getUserById(1);
   System.out.println(user2);
   MybatisUtils.closeSqlSession(sqlSession2);
}
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
[net.sf.ehcache.config.ConfigurationFactory]-Configuring ehcache from ehcache.xml found in the classpath: file:/D:/Idea-Workspace/kaka-mybatis/mybatis-08/target/classes/ehcache.xml
[net.sf.ehcache.config.ConfigurationFactory]-Configuring ehcache from URL: file:/D:/Idea-Workspace/kaka-mybatis/mybatis-08/target/classes/ehcache.xml
[net.sf.ehcache.config.ConfigurationFactory]-Configuring ehcache from InputStream
[net.sf.ehcache.config.BeanHandler]-Ignoring ehcache attribute xmlns:xsi
[net.sf.ehcache.config.BeanHandler]-Ignoring ehcache attribute xsi:noNamespaceSchemaLocation
[net.sf.ehcache.config.DiskStoreConfiguration]-Disk Store Path: D:441ehcache
[net.sf.ehcache.CacheManager]-Creating new CacheManager with default config
[net.sf.ehcache.util.PropertyUtil]-propertiesString is null.
[net.sf.ehcache.config.ConfigurationHelper]-No CacheManagerEventListenerFactory class specified. Skipping...
[net.sf.ehcache.Cache]-No BootstrapCacheLoaderFactory class specified. Skipping...
[net.sf.ehcache.Cache]-CacheWriter factory not configured. Skipping...
[net.sf.ehcache.config.ConfigurationHelper]-No CacheExceptionHandlerFactory class specified. Skipping...
[net.sf.ehcache.Cache]-No BootstrapCacheLoaderFactory class specified. Skipping...
[net.sf.ehcache.Cache]-CacheWriter factory not configured. Skipping...
[net.sf.ehcache.config.ConfigurationHelper]-No CacheExceptionHandlerFactory class specified. Skipping...
[net.sf.ehcache.store.MemoryStore]-Initialized net.sf.ehcache.store.NotifyingMemoryStore for cloud_user
[net.sf.ehcache.Cache]-Initialised cache: cloud_user
[net.sf.ehcache.config.ConfigurationHelper]-CacheDecoratorFactory not configured. Skipping for 'cloud_user'.
[net.sf.ehcache.config.ConfigurationHelper]-CacheDecoratorFactory not configured for defaultCache. Skipping for 'cloud_user'.
[net.sf.ehcache.store.MemoryStore]-Initialized net.sf.ehcache.store.MemoryStore for com.zhang.dao.UserMapper
[net.sf.ehcache.DiskStorePathManager]-Using diskstore path D:441ehcache
[net.sf.ehcache.DiskStorePathManager]-Holding exclusive lock on D:441ehcache.ehcache-diskstore.lock
[net.sf.ehcache.store.disk.DiskStorageFactory]-Failed to delete file com%002ezhang%002edao%002e%0055ser%004dapper.index
[net.sf.ehcache.store.disk.DiskStorageFactory]-Matching data file missing (or empty) for index file. Deleting index file D:441ehcachecom%002ezhang%002edao%002e%0055ser%004dapper.index
[net.sf.ehcache.store.disk.DiskStorageFactory]-Failed to delete file com%002ezhang%002edao%002e%0055ser%004dapper.index
[net.sf.ehcache.Cache]-Initialised cache: com.zhang.dao.UserMapper
[net.sf.ehcache.config.ConfigurationHelper]-CacheDecoratorFactory not configured for defaultCache. Skipping for 'com.zhang.dao.UserMapper'.
Cache Hit Ratio [com.zhang.dao.UserMapper]: 0.0
Opening JDBC Connection
Thu Apr 08 15:38:33 CST 2021 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Created connection 1585635178.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e82df6a]
==>  Preparing: select * from mybatis.user where id = ? 
==> Parameters: 1(Integer)
<==    Columns: id, name, pwd
<==        Row: 1, 卡卡罗特, 123455
<==      Total: 1
User{id=1, name='卡卡罗特', pwd='123455'}
[net.sf.ehcache.store.disk.Segment]-put added 0 on heap
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e82df6a]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e82df6a]
Returned connection 1585635178 to pool.
================================
Cache Hit Ratio [com.zhang.dao.UserMapper]: 0.5
User{id=1, name='卡卡罗特', pwd='123455'}

7、查看是否生成缓存文件

image

参数说明:

diskStore :指定数据存储位置,可指定磁盘中的文件夹位置
defaultCache : 默认的管理策略

以下属性是必须的:
name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)。maxElementsInMemory:在内存中缓存的element的最大数目。
eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断。
maxElementsInMemory:cache 中最多可以存放的元素的数量。如果放入cache中的元素超过这个数值,有两种情况:
1、若overflowToDisk的属性值为true,会将cache中多出的元素放入磁盘文件中。
2、若overflowToDisk的属性值为false,会根据memoryStoreEvictionPolicy的策略替换cache中原有的元素。
overflowToDisk: 如果内存中数据超过内存限制,是否要缓存到磁盘上。
maxElementsOnDisk:在磁盘上缓存的element的最大数目,默认值为0,表示不限制。

以下属性是可选的:
timeToIdleSeconds: 对象空闲时间,指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问。以秒为单位。
timeToLiveSeconds: 对象存活时间,指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问。以秒为单位。
diskPersistent: 是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false。
diskExpiryThreadIntervalSeconds: 对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次。以秒为单位。
diskSpoolBufferSizeMB: DiskStore使用的磁盘大小,默认值30MB。每个cache使用各自的DiskStore。
memoryStoreEvictionPolicy: 如果内存中数据超过内存限制,向磁盘缓存时的策略。默认值LRU,可选FIFO、LFU。
缓存的3 种清空策略 :
FIFO ,first in first out (先进先出).
LFU , Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
LRU ,Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

原文地址:https://www.cnblogs.com/kaka-qiqi/p/14632601.html