• Java框架 MyBatis的缓存


    0、准备工作

    1、引入依赖

    1. <dependencies>
    2.         
    3.         <dependency>
    4.             <groupId>org.mybatisgroupId>
    5.             <artifactId>mybatisartifactId>
    6.             <version>3.5.7version>
    7.         dependency>
    8.  
    9.         
    10.         <dependency>
    11.             <groupId>junitgroupId>
    12.             <artifactId>junitartifactId>
    13.             <version>4.12version>
    14.             <scope>testscope>
    15.         dependency>
    16.  
    17.         
    18.         <dependency>
    19.             <groupId>mysqlgroupId>
    20.             <artifactId>mysql-connector-javaartifactId>
    21.             <version>8.0.27version>
    22.         dependency>
    23.  
    24.         
    25.         <dependency>
    26.             <groupId>log4jgroupId>
    27.             <artifactId>log4jartifactId>
    28.             <version>1.2.17version>
    29.         dependency>
    30.     dependencies>

    2、数据表数据

    1. CREATE TABLE t_dept(
    2.     dept_id INT PRIMARY KEY AUTO_INCREMENT,
    3.     dept_name VARCHAR(20)
    4. );
    5.  
    6. CREATE TABLE t_emp(
    7.     emp_id INT PRIMARY KEY AUTO_INCREMENT,
    8.     emp_name VARCHAR(20),
    9.     age INT,
    10.     gender CHAR,
    11.     dept_id INT
    12. );
    13.  
    14. INSERT INTO t_dept(dept_name) VALUES ('A'),('B'),('C');
    15.  
    16. INSERT INTO t_emp(emp_name,age,gender,dept_id) VALUES
    17. ('张三',20,'女',1),
    18. ('李四',22,'女',2),
    19. ('王五',21,'男',3),
    20. ('赵六',23,'男',1),
    21. ('田七',21,'女',3);

    3、创建与数据表相对应 java 实体类

    1. public class Emp {
    2.     private Integer empId;
    3.     private String empName;
    4.     private Integer age;
    5.     private String gender;
    6.     private Integer deptId;
    7.  
    8.     public Emp() {
    9.     }
    10.  
    11.     public Emp(Integer empId, String empName, Integer age, String gender, Integer deptId) {
    12.         this.empId = empId;
    13.         this.empName = empName;
    14.         this.age = age;
    15.         this.gender = gender;
    16.         this.deptId = deptId;
    17.     }
    18.  
    19.     public Integer getEmpId() {
    20.         return empId;
    21.     }
    22.  
    23.     public void setEmpId(Integer empId) {
    24.         this.empId = empId;
    25.     }
    26.  
    27.     public String getEmpName() {
    28.         return empName;
    29.     }
    30.  
    31.     public void setEmpName(String empName) {
    32.         this.empName = empName;
    33.     }
    34.  
    35.     public Integer getAge() {
    36.         return age;
    37.     }
    38.  
    39.     public void setAge(Integer age) {
    40.         this.age = age;
    41.     }
    42.  
    43.     public String getGender() {
    44.         return gender;
    45.     }
    46.  
    47.     public void setGender(String gender) {
    48.         this.gender = gender;
    49.     }
    50.  
    51.     public Integer getDeptId() {
    52.         return deptId;
    53.     }
    54.  
    55.     public void setDeptId(Integer deptId) {
    56.         this.deptId = deptId;
    57.     }
    58.  
    59.     @Override
    60.     public String toString() {
    61.         return "Emp{" +
    62.                 "empId=" + empId +
    63.                 ", empName='" + empName + '\'' +
    64.                 ", age=" + age +
    65.                 ", gender='" + gender + '\'' +
    66.                 ", deptId=" + deptId +
    67.                 '}';
    68.     }
    69. }
    1. public class Dept {
    2.     private Integer deptId;
    3.     private String deptName;
    4.  
    5.     public Dept(Integer deptId, String deptName) {
    6.         this.deptId = deptId;
    7.         this.deptName = deptName;
    8.     }
    9.  
    10.     public Dept() {
    11.     }
    12.  
    13.     public Integer getDeptId() {
    14.         return deptId;
    15.     }
    16.  
    17.     public void setDeptId(Integer deptId) {
    18.         this.deptId = deptId;
    19.     }
    20.  
    21.     public String getDeptName() {
    22.         return deptName;
    23.     }
    24.  
    25.     public void setDeptName(String deptName) {
    26.         this.deptName = deptName;
    27.     }
    28.  
    29.     @Override
    30.     public String toString() {
    31.         return "Dept{" +
    32.                 "deptId=" + deptId +
    33.                 ", deptName='" + deptName + '\'' +
    34.                 '}';
    35.     }
    36. }

    4、jdbc.properties 文件

    1. jdbc.driver=com.mysql.cj.jdbc.Driver
    2. jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
    3. jdbc.username=root
    4. jdbc.password=root


    5、MyBaits 核心配置文件

    1. configuration
    2.         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    3.         "http://mybatis.org/dtd/mybatis-3-config.dtd">
    4. <configuration>
    5.     
    6.  
    7.     
    8.     <properties resource="jdbc.properties"/>
    9.  
    10.     <typeAliases>
    11.         <package name="com.chenyixin.ssm.pojo"/>
    12.     typeAliases>
    13.  
    14.     
    15.     <environments default="development">
    16.         <environment id="development">
    17.             <transactionManager type="JDBC"/>
    18.             <dataSource type="POOLED">
    19.                 <property name="driver" value="${jdbc.driver}"/>
    20.                 <property name="url" value="${jdbc.url}"/>
    21.                 <property name="username" value="${jdbc.username}"/>
    22.                 <property name="password" value="${jdbc.password}"/>
    23.             dataSource>
    24.         environment>
    25.  
    26.     environments>
    27.  
    28.     
    29.     <mappers>
    30.         
    31.         <package name="com.chenyixin.ssm.mapper"/>
    32.     mappers>
    33. configuration>

    6、工具类:

    1. package com.chenyin.ssm.utils;
    2.  
    3. import org.apache.ibatis.io.Resources;
    4. import org.apache.ibatis.session.SqlSession;
    5. import org.apache.ibatis.session.SqlSessionFactory;
    6. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    7.  
    8. import java.io.InputStream;
    9.  
    10. public class SqlSessionUtil {
    11.  
    12.     public static SqlSession getSqlSession() {
    13.         try {
    14.             // 获取核心的配置文件
    15.             InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    16.             // 创建 SqlSessionFactoryBuilder 对象
    17.             SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    18.  
    19.             // 通过核心配置文件多对应的字节输入流创建工厂类 SqlSessionFactory ,生产 SqlSession 对象
    20.             SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
    21.  
    22.             // 创建 SqlSession 对象(自动操作事务)
    23.             return sqlSessionFactory.openSession(true);
    24.         } catch (Exception e) {
    25.             throw new RuntimeException(e);
    26.         }
    27.  
    28.     }
    29. }

    7、log4j.xml配置文件

    1. log4j:configuration SYSTEM "log4j.dtd">
    2.  
    3. <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    4.  
    5.     <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
    6.         <param name="Encoding" value="UTF-8" />
    7.         <layout class="org.apache.log4j.PatternLayout">
    8.             <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
    9.         layout>
    10.     appender>
    11.     <logger name="java.sql">
    12.         <level value="debug" />
    13.     logger>
    14.     <logger name="org.apache.ibatis">
    15.         <level value="info" />
    16.     logger>
    17.     <root>
    18.         <level value="debug" />
    19.         <appender-ref ref="STDOUT" />
    20.     root>
    21. log4j:configuration>

    1、MyBatis 的一级缓存

    MyBatis 的一级缓存是 SqlSession 级别的,即通过同一个 SqlSession 查询的数据会被缓存

    再次使用同一个 SqlSession 查询同一条数据,会从缓存中获取

    1.1、代码示例:

    CacheMapper 接口:

    1. public interface CacheMapper {
    2. /**
    3. * 跟据 empId 查询员工信息
    4. * @param empId
    5. * @return
    6. */
    7. Emp getEmpByEmpId(@Param("empId") Integer empId);
    8. /**
    9. * 添加单个员工信息
    10. * @param emp
    11. * @return
    12. */
    13. int insertEmp(Emp emp);
    14. }

    CacheMapper.xml 配置文件:

    1. <mapper namespace="com.chenyixin.ssm.mapper.CacheMapper">
    2. <select id="getEmpByEmpId" resultType="emp">
    3. select *
    4. from t_emp
    5. where emp_id = #{empId}
    6. select>
    7. <insert id="insertEmp">
    8. insert into t_emp
    9. values (null, empName, age, gender, null);
    10. insert>
    11. mapper>

    测试:

    1. @Test
    2. public void getEmpByEmpId() {
    3. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    4. CacheMapper mapper1 = sqlSession.getMapper(CacheMapper.class);
    5. Emp emp1 = mapper1.getEmpByEmpId(1);
    6. Emp emp2 = mapper1.getEmpByEmpId(1);
    7. System.out.println(emp1);
    8. System.out.println(emp2);
    9. }

    结果:

    1.2、使一级缓存失效的四种情况

    使一级缓存失效的四种情况:

            1) 不同的SqlSession对应不同的一级缓存

            2) 同一个SqlSession但是查询条件不同

            3) 同一个SqlSession两次查询期间执行了任何一次增删改操作

            4) 同一个SqlSession两次查询期间手动清空了缓存

    ① 不同的SqlSession对应不同的一级缓存

    1. @Test
    2. public void test1() {
    3. SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();
    4. CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
    5. Emp emp1 = mapper1.getEmpByEmpId(1);
    6. Emp emp2 = mapper1.getEmpByEmpId(1);
    7. System.out.println(emp1);
    8. System.out.println(emp2);
    9. SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();
    10. CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
    11. Emp emp3 = mapper2.getEmpByEmpId(1);
    12. System.out.println(emp3);
    13. }

    结果:

    ② 同一个SqlSession但是查询条件不同

    1. @Test
    2. public void test2() {
    3. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    4. CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
    5. Emp emp1 = mapper.getEmpByEmpId(1);
    6. System.out.println(emp1);
    7. Emp emp2 = mapper.getEmpByEmpId(2);
    8. System.out.println(emp2);
    9. }

     结果:

    ③ 同一个SqlSession两次查询期间执行了任何一次增删改操作

    1. @Test
    2. public void test3() {
    3. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    4. CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
    5. Emp emp1 = mapper.getEmpByEmpId(1);
    6. System.out.println(emp1);
    7. int i = mapper.insertEmp(new Emp(null, "小红", 23, "男"));
    8. System.out.println(i);
    9. Emp emp2 = mapper.getEmpByEmpId(1);
    10. System.out.println(emp2);
    11. }

    结果:

    ④ 同一个SqlSession两次查询期间手动清空了缓存

    1. @Test
    2. public void test4() {
    3. SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    4. CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
    5. Emp emp1 = mapper.getEmpByEmpId(1);
    6. System.out.println(emp1);
    7. sqlSession.clearCache();
    8. Emp emp2 = mapper.getEmpByEmpId(2);
    9. System.out.println(emp2);
    10. }

    结果:

    2、MyBatis 的二级缓存

    MyBatis 的二级缓存是 SqlSessionFactory 级别的,即通过同一个 SqlSessionFactory 所获取的 SqlSession 对象

    查询的数据会被缓存,在通过同一个 SqlSessionFactory 所获取的 SqlSession 查询相同的数据会从缓存中获取

    MyBatis 的二级缓存开启的条件:

            a>在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置

            b>在映射文件中设置标签

            c>二级缓存必须在SqlSession关闭或提交之后有效

            d>查询的数据所转换的实体类类型必须实现序列化的接口 

    代码示例:

    1、在映射文件中设置标签

     2、二级缓存必须在SqlSession关闭或提交之后有效

    1. @Test
    2. public void test5() throws IOException {
    3. InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    4. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    5. SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
    6. CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
    7. Emp emp1 = mapper1.getEmpByEmpId(1);
    8. System.out.println(emp1);
    9. // 需要关闭 SqlSession 对象 ,数据会从一级缓存被保存到二级缓存
    10. sqlSession1.close();
    11. SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
    12. CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
    13. Emp emp2 = mapper2.getEmpByEmpId(1);
    14. System.out.println(emp2);
    15. sqlSession2.close();
    16. }

    3、查询的数据所转换的实体类类型必须实现序列化的接口

     结果:

    3、二级缓存的相关配置

    在mapper配置文件中添加的cache标签可以设置一些属性:
    eviction属性:缓存回收策略,默认的是 LRU。        
            LRU(Least Recently Used最近最少使用的:移除最长时间不被使用的对象。
            FIFO(First in First out先进先出:按对象进入缓存的顺序来移除它们。
            SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
            WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
    flushInterval属性:刷新间隔,单位毫秒
            默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
    size属性:引用数目,正整数
            代表缓存最多可以存储多少个对象,太大容易导致内存溢出
    readOnly属性:只读, true/false
            true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了 很重要的性能优势。
            false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。

    4、MyBatis缓存查询的顺序

    先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
    如果二级缓存没有命中,再查询一级缓存
    如果一级缓存也没有命中,则查询数据库
    SqlSession关闭之后,一级缓存中的数据会写入二级缓存

    5、整合第三方缓存EHCache

    5.1、添加依赖

    1. <dependency>
    2. <groupId>org.mybatis.cachesgroupId>
    3. <artifactId>mybatis-ehcacheartifactId>
    4. <version>1.2.1version>
    5. dependency>
    6. <dependency>
    7. <groupId>ch.qos.logbackgroupId>
    8. <artifactId>logback-classicartifactId>
    9. <version>1.2.3version>
    10. dependency>

    5.2、各jar包功能

    jar包名称

    作用

    mybatis-ehcache

    Mybatis和EHCache的整合包

    ehcache

    EHCache核心包

    slf4j-api

    SLF4J日志门面包

    logback-classic

    支持SLF4J门面接口的一个具体实现

    5.3、创建EHCache的配置文件ehcache.xml

    注意:配置文件名 ehcache.xml 不可更改

    1. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    3. <diskStore path="E:\java\temp"/>
    4. <defaultCache maxElementsInMemory="1000"
    5. maxElementsOnDisk="10000000"
    6. eternal="false"
    7. overflowToDisk="true"
    8. timeToIdleSeconds="120"
    9. timeToLiveSeconds="120"
    10. diskExpiryThreadIntervalSeconds="120"
    11. memoryStoreEvictionPolicy="LRU">
    12. defaultCache>
    13. ehcache>

    5.4、设置二级缓存的类型

    mapper配置文件中添加的cache标签可以设置二级缓存的类型:

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

    5.5、加入logback日志

            存在SLF4J时,作为简易日志的log4j将失效,此时我们需要借助SLF4J的具体实现logback来打印日志。 创建logback的配置文件logback.xml  注意:配置文件名 logback.xml 不可更改
    1. <configuration debug="true">
    2. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    3. <encoder>
    4. <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger]
    5. [%msg]%n
    6. pattern>
    7. encoder>
    8. appender>
    9. <root level="DEBUG">
    10. <appender-ref ref="STDOUT"/>
    11. root>
    12. <logger name="com.chenyixin.ssm.mapper" level="DEBUG"/>
    13. configuration>

    根据特殊需求指定局部日志级别 --》需要更改路径

    5.6、EHCache配置文件说明

    5.7、测试

    1. @Test
    2. public void test5() throws IOException {
    3. InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    4. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    5. SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
    6. CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
    7. Emp emp1 = mapper1.getEmpByEmpId(1);
    8. System.out.println(emp1);
    9. // 需要关闭 SqlSession 对象 ,数据会从一级缓存被保存到二级缓存
    10. sqlSession1.close();
    11. SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
    12. CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
    13. Emp emp2 = mapper2.getEmpByEmpId(1);
    14. System.out.println(emp2);
    15. sqlSession2.close();
    16. }

    5.8、结果

    14:58:53,497 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
    14:58:53,498 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
    14:58:53,498 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/logback.xml]
    14:58:53,560 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
    14:58:53,562 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
    14:58:53,566 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
    14:58:53,585 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
    14:58:53,585 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
    14:58:53,587 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.chenyixin.ssm.mapper] to DEBUG
    14:58:53,587 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
    14:58:53,587 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@12c8a2c0 - Registering current configuration as safe fallback point
    [14:58:53.590] [DEBUG] [main] [org.apache.ibatis.logging.LogFactory]
                    [Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.]
    [14:58:53.594] [DEBUG] [main] [org.apache.ibatis.io.VFS]
                    [Class not found: org.jboss.vfs.VFS]
    [14:58:53.594] [DEBUG] [main] [org.apache.ibatis.io.JBoss6VFS]
                    [JBoss 6 VFS API is not available in this environment.]
    [14:58:53.594] [DEBUG] [main] [org.apache.ibatis.io.VFS]
                    [Class not found: org.jboss.vfs.VirtualFile]
    [14:58:53.594] [DEBUG] [main] [org.apache.ibatis.io.VFS]
                    [VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.]
    [14:58:53.594] [DEBUG] [main] [org.apache.ibatis.io.VFS]
                    [Using VFS adapter org.apache.ibatis.io.DefaultVFS]
    [14:58:53.595] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/pojo]
    [14:58:53.595] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/pojo]
    [14:58:53.619] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: Dept.class]
    [14:58:53.619] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: Emp.class]
    [14:58:53.619] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Listing file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/pojo]
    [14:58:53.619] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/pojo/Dept.class]
    [14:58:53.619] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/pojo/Dept.class]
    [14:58:53.625] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: ����   4 =]
    [14:58:53.625] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/pojo/Emp.class]
    [14:58:53.625] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/pojo/Emp.class]
    [14:58:53.625] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: ����   4 K]
    [14:58:53.625] [DEBUG] [main] [org.apache.ibatis.io.ResolverUtil]
                    [Checking to see if class com.chenyixin.ssm.pojo.Dept matches criteria [is assignable to Object]]
    [14:58:53.627] [DEBUG] [main] [org.apache.ibatis.io.ResolverUtil]
                    [Checking to see if class com.chenyixin.ssm.pojo.Emp matches criteria [is assignable to Object]]
    [14:58:53.640] [DEBUG] [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]
                    [PooledDataSource forcefully closed/removed all connections.]
    [14:58:53.640] [DEBUG] [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]
                    [PooledDataSource forcefully closed/removed all connections.]
    [14:58:53.640] [DEBUG] [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]
                    [PooledDataSource forcefully closed/removed all connections.]
    [14:58:53.640] [DEBUG] [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]
                    [PooledDataSource forcefully closed/removed all connections.]
    [14:58:53.641] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/test-classes/com/chenyixin/ssm/mapper]
    [14:58:53.641] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/test-classes/com/chenyixin/ssm/mapper]
    [14:58:53.641] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: CacheMapperTest.class]
    [14:58:53.641] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Listing file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/test-classes/com/chenyixin/ssm/mapper]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/test-classes/com/chenyixin/ssm/mapper/CacheMapperTest.class]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/test-classes/com/chenyixin/ssm/mapper/CacheMapperTest.class]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: ����   4 {]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/mapper]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/mapper]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: CacheMapper.class]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: CacheMapper.xml]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Listing file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/mapper]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/mapper/CacheMapper.class]
    [14:58:53.642] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/mapper/CacheMapper.class]
    [14:58:53.644] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: ����   4 ]
    [14:58:53.644] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Find JAR URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/mapper/CacheMapper.xml]
    [14:58:53.644] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Not a JAR: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/com/chenyixin/ssm/mapper/CacheMapper.xml]
    [14:58:53.645] [DEBUG] [main] [org.apache.ibatis.io.DefaultVFS]
                    [Reader entry: ]
    [14:58:53.645] [DEBUG] [main] [org.apache.ibatis.io.ResolverUtil]
                    [Checking to see if class com.chenyixin.ssm.mapper.CacheMapperTest matches criteria [is assignable to Object]]
    [14:58:53.645] [DEBUG] [main] [org.apache.ibatis.io.ResolverUtil]
                    [Checking to see if class com.chenyixin.ssm.mapper.CacheMapper matches criteria [is assignable to Object]]
    [14:58:53.665] [DEBUG] [main] [net.sf.ehcache.config.ConfigurationFactory]
                    [Configuring ehcache from ehcache.xml found in the classpath: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/ehcache.xml]
    [14:58:53.666] [DEBUG] [main] [net.sf.ehcache.config.ConfigurationFactory]
                    [Configuring ehcache from URL: file:/E:/java/java%e5%ad%a6%e4%b9%a0/SSM/pro05-MyBatis-cache/target/classes/ehcache.xml]
    [14:58:53.667] [DEBUG] [main] [net.sf.ehcache.config.ConfigurationFactory]
                    [Configuring ehcache from InputStream]
    [14:58:53.674] [DEBUG] [main] [net.sf.ehcache.config.BeanHandler]
                    [Ignoring ehcache attribute xmlns:xsi]
    [14:58:53.674] [DEBUG] [main] [net.sf.ehcache.config.BeanHandler]
                    [Ignoring ehcache attribute xsi:noNamespaceSchemaLocation]
    [14:58:53.674] [DEBUG] [main] [net.sf.ehcache.config.DiskStoreConfiguration]
                    [Disk Store Path: E:\java\temp]
    [14:58:53.682] [DEBUG] [main] [net.sf.ehcache.CacheManager]
                    [Creating new CacheManager with default config]
    [14:58:53.683] [DEBUG] [main] [net.sf.ehcache.util.PropertyUtil]
                    [propertiesString is null.]
    [14:58:53.688] [DEBUG] [main] [net.sf.ehcache.config.ConfigurationHelper]
                    [No CacheManagerEventListenerFactory class specified. Skipping...]
    [14:58:53.843] [DEBUG] [main] [net.sf.ehcache.Cache]
                    [No BootstrapCacheLoaderFactory class specified. Skipping...]
    [14:58:53.843] [DEBUG] [main] [net.sf.ehcache.Cache]
                    [CacheWriter factory not configured. Skipping...]
    [14:58:53.843] [DEBUG] [main] [net.sf.ehcache.config.ConfigurationHelper]
                    [No CacheExceptionHandlerFactory class specified. Skipping...]
    [14:58:53.858] [DEBUG] [main] [net.sf.ehcache.DiskStorePathManager]
                    [Using diskstore path E:\java\temp]
    [14:58:53.858] [DEBUG] [main] [net.sf.ehcache.DiskStorePathManager]
                    [Holding exclusive lock on E:\java\temp\.ehcache-diskstore.lock]
    [14:58:53.858] [DEBUG] [main] [net.sf.ehcache.store.disk.DiskStorageFactory]
                    [Failed to delete file com%002echenyixin%002essm%002emapper%002e%0043ache%004dapper.data]
    [14:58:53.858] [DEBUG] [main] [net.sf.ehcache.store.disk.DiskStorageFactory]
                    [Failed to delete file com%002echenyixin%002essm%002emapper%002e%0043ache%004dapper.index]
    [14:58:53.861] [DEBUG] [main] [net.sf.ehcache.store.disk.DiskStorageFactory]
                    [Matching data file missing (or empty) for index file. Deleting index file E:\java\temp\com%002echenyixin%002essm%002emapper%002e%0043ache%004dapper.index]
    [14:58:53.863] [DEBUG] [main] [net.sf.ehcache.store.disk.DiskStorageFactory]
                    [Failed to delete file com%002echenyixin%002essm%002emapper%002e%0043ache%004dapper.index]
    [14:58:53.901] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Pass-Through Statistic: LOCAL_OFFHEAP_SIZE]
    [14:58:53.902] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Pass-Through Statistic: LOCAL_OFFHEAP_SIZE_BYTES]
    [14:58:53.902] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Pass-Through Statistic: WRITER_QUEUE_LENGTH]
    [14:58:53.902] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Pass-Through Statistic: REMOTE_SIZE]
    [14:58:53.902] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Pass-Through Statistic: LAST_REJOIN_TIMESTAMP]
    [14:58:53.908] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: OFFHEAP_GET]
    [14:58:53.908] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: OFFHEAP_PUT]
    [14:58:53.909] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: OFFHEAP_REMOVE]
    [14:58:53.909] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: XA_COMMIT]
    [14:58:53.909] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: XA_ROLLBACK]
    [14:58:53.910] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: XA_RECOVERY]
    [14:58:53.910] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: CLUSTER_EVENT]
    [14:58:53.910] [DEBUG] [main] [net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl]
                    [Mocking Operation Statistic: NONSTOP]
    [14:58:53.915] [DEBUG] [main] [net.sf.ehcache.Cache]
                    [Initialised cache: com.chenyixin.ssm.mapper.CacheMapper]
    [14:58:53.916] [DEBUG] [main] [net.sf.ehcache.config.ConfigurationHelper]
                    [CacheDecoratorFactory not configured for defaultCache. Skipping for 'com.chenyixin.ssm.mapper.CacheMapper'.]
    [14:58:53.963] [DEBUG] [main] [com.chenyixin.ssm.mapper.CacheMapper]
                    [Cache Hit Ratio [com.chenyixin.ssm.mapper.CacheMapper]: 0.0]
    [14:58:53.966] [DEBUG] [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction]
                    [Opening JDBC Connection]
    [14:58:54.376] [DEBUG] [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]
                    [Created connection 826865256.]
    [14:58:54.380] [DEBUG] [main] [com.chenyixin.ssm.mapper.CacheMapper.getEmpByEmpId]
                    [==>  Preparing: select * from t_emp where emp_id = ?]
    [14:58:54.405] [DEBUG] [main] [com.chenyixin.ssm.mapper.CacheMapper.getEmpByEmpId]
                    [==> Parameters: 1(Integer)]
    [14:58:54.420] [DEBUG] [main] [com.chenyixin.ssm.mapper.CacheMapper.getEmpByEmpId]
                    [<==      Total: 1]
    Emp{empId=1, empName='张三', age=20, gender='女', dept=null}
    [14:58:54.422] [DEBUG] [main] [net.sf.ehcache.store.disk.Segment]
                    [put added 0 on heap]
    [14:58:54.423] [DEBUG] [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction]
                    [Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3148f668]]
    [14:58:54.423] [DEBUG] [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]
                    [Returned connection 826865256 to pool.]
    [14:58:54.423] [DEBUG] [main] [com.chenyixin.ssm.mapper.CacheMapper]
                    [Cache Hit Ratio [com.chenyixin.ssm.mapper.CacheMapper]: 0.5]
    Emp{empId=1, empName='张三', age=20, gender='女', dept=null}

    进程已结束,退出代码0
     

    结果可以看出:查询语句只执行力了一次

  • 相关阅读:
    C++:stl_List的介绍与模拟实现
    python基础语法(二)
    SQL多个字段拼接组合成新字段的常用方法
    viple进阶4:打印空心三角形
    【Android笔记01】Android Studio开发工具安装及虚拟设备访问APP应用
    vue中v-bind和v-model有什么区别
    学习视觉SLAM需要会些什么?
    docker CLI官方教程 run方法解析(docer run 、docker attach 与 docker exec的区别)
    华为率先商用卫星通信技术,有助中国在6G技术上取得领先优势
    Spring注解@NonNull作用 Spring注解@Nullable作用 Spring NonNull 注解作用 Spring Nullable注解作用
  • 原文地址:https://blog.csdn.net/weixin_65637841/article/details/126325009