接上篇案例………..接上篇案例………..接上篇案例………..
-
简述
内存中的一块存储空间,服务于某个应用程序,旨在将频繁读取的数据临时保存在内存中,便于二次快速访问。

简单来说,当没有缓存时,用户想要多次访问同一组数据时,程序需要多次直接访问数据库,耽误时间,并且产生大量无用操作,间接消耗设备。而当有了缓存操作后,程序只会在第一次查询数据时直接访问数据库,用户再次访问时,直接访问缓存空间即可,无需持续访问数据库,提高运行效率,节省资源!
-
创建数据表
CREATE TABLE `t_car` (
`id` INT(11) PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(256),
`brand` VARCHAR(256),
`price` DOUBLE,
`color` VARCHAR(256),
`num` INT(11)
) ENGINE = INNODB CHARACTER SET = utf8;
INSERT INTO t_car(NAME,brand,price,color,num) VALUES('法拉利','大众',200000,'黑色',5000);
INSERT INTO t_car(NAME,brand,price,color,num) VALUES('帕萨特','大众',200000,'黑色',6000);
INSERT INTO t_car(NAME,brand,price,color,num) VALUES('布加迪威龙','保时捷',700000,'白色',2000);
INSERT INTO t_car(NAME,brand,price,color,num) VALUES('奥迪A8','奥迪',300000,'白色',3000);
INSERT INTO t_car(NAME,brand,price,color,num) VALUES('宝马X9','宝马',500000,'黑色',2000);
INSERT INTO t_car(NAME,brand,price,color,num) VALUES('雅阁','本田',180000,'黑色',3000);
-
创建实体类
@Data
public class Car implements Serializable {
private Integer id;
private String name;
private String brand;
private Double price;
private String color;
private Integer num;
}
-
一级缓存
SqlSession级别的缓存,同一个SqlSession的发起多次同构查询,会将数据保存在一级缓存中
注:无需任何配置,默认开启一级缓存
-
在CarMapper中添加相关方法
public interface CarMapper {
//查询单个
public Car findById(Integer id);
}
-
在CarMapper.xml中添加相关代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cj.mapper.CarMapper">
<!-- 开启二级缓存 -->
<cache></cache>
<resultMap id="carMap" type="com.cj.pojo.Car">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="brand" column="brand"></result>
<result property="price" column="price"></result>
<result property="color" column="color"></result>
<result property="num" column="num"></result>
</resultMap>
<!-- sql片段:提取重复性的sql语句-->
<sql id="baseSql">
select id,name,brand,price,color,num from t_car
</sql>
<!-- 查询单个 -->
<select id="findById" resultMap="carMap">
<!-- 引入sql片段 -->
<include refid="baseSql"></include>
<where>
id = #{id}
</where>
</select>
</mapper>
-
在测试类中进行测试
/**
* 测试一级缓存:SqlSession级别
*/
@Test
public void testCache1() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//使用同一个sqlSession进行操作
SqlSession sqlSession = sessionFactory.openSession();
//一旦手动清空缓存,或者进行增删改操作,执行了commit(),close()方法了,也会清空一级缓存
CarMapper carMapper = sqlSession.getMapper(CarMapper.class);
Car car1 = carMapper.findById(1);
//清空缓存
//sqlSession.clearCache();
Car car2 = carMapper.findById(1);
//验证一级缓存是否存在
System.out.println(car1 == car2);
//关闭
sqlSession.close();
inputStream.close();
}
-
二级缓存
SqlSessionFactory级别的缓存,同一个SqlSessionFactory构建的不同SqlSession发起的多次同构查询,会将数据保存在二级缓存中
注:在sqlSession.commit()或者sqlSession.close()之后生效。
5.1开启全局缓存
< settings >是MyBatis中极为重要的调整设置,他们会改变MyBatis的运行行为,其他详细配置可参考官方文档。
-
在MyBatis.xml中添加相关代码
< settings >是MyBatis中极为重要的调整设置,他们会改变MyBatis的运行行为,其他详细配置可参考官方文档。
<configuration>
<properties .../>
<!-- 注意书写位置 -->
<settings>
<setting name="cacheEnabled" value="true"/> <!-- mybaits-config.xml中开启全局缓存(默认开启) -->
</settings>
<typeAliases></typeAliases>
</configuration>
参考(MyBatis.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入配置文件 -->
<properties resource="db.properties"></properties>
<!-- 配置日志 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
<!-- 一级缓存失效-->
<setting name="localCacheScope" value="STATEMENT"/>
<!-- 注意书写位置 -->
<settings>
<setting name="cacheEnabled" value="true"/> <!-- mybaits-config.xml中开启全局缓存(默认开启) -->
</settings>
</settings>
<!-- 环境配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 使用Druid连接池 -->
<dataSource type="com.qf.utils.MyDruidDataSourceFactory">
<property name="driverClassName" value="${db.driverClassName}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<!-- Mapper配置 -->
<mappers>
<!--<mapper resource="com/qf/mapper/PassengerMapper.xml"/>-->
<!-- 以包的形式来写 -->
<package name="com.cj.mapper"/>
</mappers>
</configuration>
5.2测试
/**
* 测试二级缓存:sessionFactory级别
*/
@Test
public void testCache2() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//不同的sqlSession对象,缓存的数据只在当前sqlSession中,和其他的sqlSession没关系
SqlSession sqlSession1 = sessionFactory.openSession();
CarMapper carMapper1 = sqlSession1.getMapper(CarMapper.class);
Car car1 = carMapper1.findById(1);
sqlSession1.close();
SqlSession sqlSession2 = sessionFactory.openSession();
CarMapper carMapper2 = sqlSession2.getMapper(CarMapper.class);
Car car2 = carMapper2.findById(1);
//先不关闭sqlSession
inputStream.close();
}
注意:在开启二级缓存时,要将</cache>添加到相对应的XXXMapper.xml代码中