0、准备工作
1、引入依赖
<dependencies>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
2、数据表数据
CREATE TABLE t_dept(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE t_emp(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
age INT,
gender CHAR,
dept_id INT
);
INSERT INTO t_dept(dept_name) VALUES ('A'),('B'),('C');
INSERT INTO t_emp(emp_name,age,gender,dept_id) VALUES
('张三',20,'女',1),
('李四',22,'女',2),
('王五',21,'男',3),
('赵六',23,'男',1),
('田七',21,'女',3);
3、创建与数据表相对应 java 实体类
public class Emp {
private Integer empId;
private String empName;
private Integer age;
private String gender;
private Integer deptId;
public Emp() {
}
public Emp(Integer empId, String empName, Integer age, String gender, Integer deptId) {
this.empId = empId;
this.empName = empName;
this.age = age;
this.gender = gender;
this.deptId = deptId;
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Override
public String toString() {
return "Emp{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", deptId=" + deptId +
'}';
}
}
public class Dept {
private Integer deptId;
private String deptName;
public Dept(Integer deptId, String deptName) {
this.deptId = deptId;
this.deptName = deptName;
}
public Dept() {
}
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "Dept{" +
"deptId=" + deptId +
", deptName='" + deptName + '\'' +
'}';
}
}
4、jdbc.properties 文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=root
5、MyBaits 核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
MyBatis核心配置文件中,标签的顺序:
properties?,settings?,typeAliases?,typeHandlers?, objectFactory?,objectWrapperFactory?,
reflectorFactory?, plugins?,environments?,databaseIdProvider?,mappers?
-->
<!-- 引入 properties 文件 ,此后可以在当前文件中使用的方式访问value-->
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="com.chenyixin.ssm.pojo"/>
</typeAliases>
<!--设置连接数据库的环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<!--<mapper resource=""/>-->
<package name="com.chenyixin.ssm.mapper"/>
</mappers>
</configuration>
6、工具类:
package com.chenyin.ssm.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class SqlSessionUtil {
public static SqlSession getSqlSession() {
try {
// 获取核心的配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
// 创建 SqlSessionFactoryBuilder 对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 通过核心配置文件多对应的字节输入流创建工厂类 SqlSessionFactory ,生产 SqlSession 对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
// 创建 SqlSession 对象(自动操作事务)
return sqlSessionFactory.openSession(true);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
7、log4j.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
1、MyBatis 的一级缓存
MyBatis 的一级缓存是 SqlSession 级别的,即通过同一个 SqlSession 查询的数据会被缓存
再次使用同一个 SqlSession 查询同一条数据,会从缓存中获取
1.1、代码示例:
CacheMapper 接口:
public interface CacheMapper {
/**
* 跟据 empId 查询员工信息
* @param empId
* @return
*/
Emp getEmpByEmpId(@Param("empId") Integer empId);
/**
* 添加单个员工信息
* @param emp
* @return
*/
int insertEmp(Emp emp);
}
CacheMapper.xml 配置文件:
<mapper namespace="com.chenyixin.ssm.mapper.CacheMapper">
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpByEmpId" resultType="emp">
select *
from t_emp
where emp_id = #{empId}
</select>
<!--int insertEmp(Emp emp);-->
<insert id="insertEmp">
insert into t_emp
values (null, empName, age, gender, null);
</insert>
</mapper>
测试:
@Test
public void getEmpByEmpId() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
CacheMapper mapper1 = sqlSession.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpByEmpId(1);
Emp emp2 = mapper1.getEmpByEmpId(1);
System.out.println(emp1);
System.out.println(emp2);
}
结果:
1.2、使一级缓存失效的四种情况
使一级缓存失效的四种情况:
1) 不同的SqlSession对应不同的一级缓存
2) 同一个SqlSession但是查询条件不同
3) 同一个SqlSession两次查询期间执行了任何一次增删改操作
4) 同一个SqlSession两次查询期间手动清空了缓存
① 不同的SqlSession对应不同的一级缓存
@Test
public void test1() {
SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpByEmpId(1);
Emp emp2 = mapper1.getEmpByEmpId(1);
System.out.println(emp1);
System.out.println(emp2);
SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp3 = mapper2.getEmpByEmpId(1);
System.out.println(emp3);
}
结果:
② 同一个SqlSession但是查询条件不同
@Test
public void test2() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
Emp emp1 = mapper.getEmpByEmpId(1);
System.out.println(emp1);
Emp emp2 = mapper.getEmpByEmpId(2);
System.out.println(emp2);
}
结果:
③ 同一个SqlSession两次查询期间执行了任何一次增删改操作
@Test
public void test3() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
Emp emp1 = mapper.getEmpByEmpId(1);
System.out.println(emp1);
int i = mapper.insertEmp(new Emp(null, "小红", 23, "男"));
System.out.println(i);
Emp emp2 = mapper.getEmpByEmpId(1);
System.out.println(emp2);
}
结果:
④ 同一个SqlSession两次查询期间手动清空了缓存
@Test
public void test4() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
Emp emp1 = mapper.getEmpByEmpId(1);
System.out.println(emp1);
sqlSession.clearCache();
Emp emp2 = mapper.getEmpByEmpId(2);
System.out.println(emp2);
}
结果:
2、MyBatis 的二级缓存
MyBatis 的二级缓存是 SqlSessionFactory 级别的,即通过同一个 SqlSessionFactory 所获取的 SqlSession 对象
查询的数据会被缓存,在通过同一个 SqlSessionFactory 所获取的 SqlSession 查询相同的数据会从缓存中获取
MyBatis 的二级缓存开启的条件:
a>在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
b>在映射文件中设置标签<cache/>
c>二级缓存必须在SqlSession关闭或提交之后有效
d>查询的数据所转换的实体类类型必须实现序列化的接口
代码示例:
1、在映射文件中设置标签<cache/>
2、二级缓存必须在SqlSession关闭或提交之后有效
@Test
public void test5() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpByEmpId(1);
System.out.println(emp1);
// 需要关闭 SqlSession 对象 ,数据会从一级缓存被保存到二级缓存
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp2 = mapper2.getEmpByEmpId(1);
System.out.println(emp2);
sqlSession2.close();
}
3、查询的数据所转换的实体类类型必须实现序列化的接口
结果:
3、二级缓存的相关配置
①eviction属性:缓存回收策略,默认的是 LRU。LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。②flushInterval属性:刷新间隔,单位毫秒默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新③size属性:引用数目,正整数代表缓存最多可以存储多少个对象,太大容易导致内存溢出④readOnly属性:只读, true/falsetrue:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了 很重要的性能优势。false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。
4、MyBatis缓存查询的顺序
5、整合第三方缓存EHCache
5.1、添加依赖
<!-- Mybatis EHCache整合包 -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version>
</dependency>
<!-- slf4j日志门面的一个具体实现 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
5.2、各jar包功能
jar包名称 | 作用 |
mybatis-ehcache | Mybatis和EHCache的整合包 |
ehcache | EHCache核心包 |
slf4j-api | SLF4J日志门面包 |
logback-classic | 支持SLF4J门面接口的一个具体实现 |
5.3、创建EHCache的配置文件ehcache.xml
注意:配置文件名 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="E:\java\temp"/>
<defaultCache maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
5.4、设置二级缓存的类型
mapper配置文件中添加的cache标签可以设置二级缓存的类型:
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
5.5、加入logback日志
存在SLF4J时,作为简易日志的log4j将失效,此时我们需要借助SLF4J的具体实现logback来打印日志。 创建logback的配置文件logback.xml 注意:配置文件名 logback.xml 不可更改
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<!-- 指定日志输出的位置 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日志输出的格式 -->
<!-- 按照顺序分别是: 时间、日志级别、线程名称、打印日志的类、日志主体内容、换行
-->
<pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger]
[%msg]%n
</pattern>
</encoder>
</appender>
<!-- 设置全局日志级别。日志级别按顺序分别是: DEBUG、INFO、WARN、ERROR -->
<!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
<root level="DEBUG">
<!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->
<appender-ref ref="STDOUT"/>
</root>
<!-- 根据特殊需求指定局部日志级别 -->
<logger name="com.chenyixin.ssm.mapper" level="DEBUG"/>
</configuration>
根据特殊需求指定局部日志级别 --》需要更改路径
5.6、EHCache配置文件说明
5.7、测试
@Test
public void test5() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpByEmpId(1);
System.out.println(emp1);
// 需要关闭 SqlSession 对象 ,数据会从一级缓存被保存到二级缓存
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp2 = mapper2.getEmpByEmpId(1);
System.out.println(emp2);
sqlSession2.close();
}
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: <?xml version="1.0" encoding="UTF-8" ?>]
[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
结果可以看出:查询语句只执行力了一次