Mybatis整合第三方缓存ehcache


第三方缓存主要是来壮大Mybatis的二级缓存。

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

解读:

1、客户从数据库获取数据视为一次会话,抽象为sqlSession对象

2、一个Excutor包含增删改查的操作;

3、CachingExcutor是对Excutor的包装,此处相当于代理模式

4、当有会话时,先访问CachingExcutor对象,CachingExcutor先从二级缓存查找数据,如果有就直接返回;如果没有,就进入Excutor的一级缓存,如果还是没有就执行Excutor的增删改查返回结果,并将结果保存至缓存中,同一个sqlSession再次访问就可以从一级缓存中取了;

5、由于mybatis的缓存只用了map实现,所以mybatis允许缓存由第三方缓存来实现,并定义了cache接口,第三方只要实现该接口即可,和mybatis整合在一起后由mybatis在程序中进行调用;

一、下载相关jar包

1、下载ehcache源码包

下载地址:https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core/2.6.8

或者,用maven导入:

<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.6.8</version>
</dependency>

如图:

2、下载其依赖的日志包sl4j

2.1 下载slf4j-api.jar包

https://mvnrepository.com/artifact/org.slf4j/slf4j-api/1.7.25

或者maven配置:

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

2.2 下载slf4j-log4j12.jar包

https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12

或者maven配置:

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
    <scope>test</scope>
</dependency>

如图:

3、下载mybatis和ehcache的适配包

方式一:github上下载

https://github.com/mybatis/ehcache-cache/releases

方式二:maven仓库中下载

https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache/1.0.3

方式三:maven配置自动导入

<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.3</version>
</dependency>

如图:

4、还需要一个ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <!-- 磁盘保存路径 -->
 <diskStore path="D:\44\ehcache" />

 <defaultCache 
   maxElementsInMemory="1" 
   maxElementsOnDisk="10000000"
   eternal="false" 
   overflowToDisk="true" 
   timeToIdleSeconds="120"
   timeToLiveSeconds="120" 
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</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(先进先出)
 -->

二、整合mybatis

1、将准备好的jar包和xml导入到项目中

2、mapper.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 namespace="com.atguigu.mybatis.dao.EmployeeMapper">

    <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

    <!--public Map<Integer, Employee> getEmpByLastNameLikeReturnMap(String lastName);  -->
    <select id="getEmpByLastNameLikeReturnMap" resultType="com.atguigu.mybatis.bean.Employee">
        select * from tbl_employee where last_name like #{lastName}
    </select>
</mapper>

3、测试

@Test
public void testSecondLevelCache() throws IOException{
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    SqlSession openSession = sqlSessionFactory.openSession();
    SqlSession openSession2 = sqlSessionFactory.openSession();
    try{

        EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
        EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);

        Employee emp01 = mapper.getEmpById(1);
        System.out.println(emp01);
        openSession.close();

        //第二次查询是从二级缓存中拿到的数据,并没有发送新的sql
        Employee emp02 = mapper2.getEmpById(1);
        System.out.println(emp02);
        openSession2.close();

    }finally{

    }
}

结果:

说明: 只查询了一次sql,所以第二次访问是从ehcache缓存中拿的,

并且在D:\44\ehcache目录下也会有相关数据:

注: 如果其他mapper.xml需要使用缓存,可进行引用mapper

<cache-ref namespace="com.atguigu.mybatis.dao.EmployeeMapper"/>


原文链接:https://blog.csdn.net/jinhaijing/article/details/84255107