Mybatis的一级缓存和二级缓存
验证mybatis缓存的存在,以及一级缓存如何保证数据一致性
文章共4,036字 · 阅读需要大约14分钟
一键AI生成摘要,助你高效阅读
问答
·
一.Mybatis缓存
什么是Mybatis缓存?
Mybatis为了提高查询的效率,内置了缓存机制。
缓存:把经常访问但是不经常修改的数据存储在缓存内容中,减少与数据库交互,从而达到提高效率的目的
Mybatis因为缓存的位置不一样又分为了2种缓存:一级缓存 和二级缓存
一级缓存的数据存储在SqlSession对象里面
二级缓存的数据存储在SqlSessionFactory对象里面
1 .一级缓存
一级缓存特点:
一级缓存,默认存在,无法关闭
缓存的数据存储在SQLSession对象中(类似Map集合,键对应的sql语句,值就是语句对应的结果)
一级缓存如何保证数据一致性的:
当执行查询语句时,自动走缓存,缓存中如果有数据就返回,缓存没有就查询数据库,更新缓存
当执行非查询语句时(新增、修改、删除),就会自动删除缓存
接下来通过代码演示来验证缓存的存在
在验证之前先了解下Mybatis的日志如何配置,通过日志我们可以在控制台看到sql语句的打印信息
Mybatis内置的有日志记录,但是需要配置才会生效
日志配置步骤:
导入依赖jar
<!-- 日志处理 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
在mybatis-config.xml中开启日志
<settings>
<!-- 开启日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
通过代码演示来验证缓存的存在
1)准备数据表
create table t_phone(
id int primary key auto_increment,
name varchar(20),
brand char(2),
model varchar(11),
price decimal(10,2),
ctime datetime
);
2).在pom.xml中导入所需要的依赖
<dependencies>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<!--小辣椒-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
3).创建Phone实体类
@Data
@NoArgsConstructor
public class Phone implements Serializable {
private Integer id;
private String name;
private String brand;
private String model;
private Double price;
private Date ctime;
public Phone(String name, String brand, String model, Double price) {
this.name = name;
this.brand = brand;
this.model = model;
this.price = price;
}
}
4).创建mapper接口(编写操作数据库的各种方法)
public interface PhoneDao {
/**
* 新增*/
int add(Phone phone);
/**
* 查询*/
List<Phone> selectAll();
}
5)创建mapper接口对应的映射文件(编写方法对应的sql语句)
<?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.feri.mybatis.dao.PhoneDao">
<insert id="add" useGeneratedKeys="true" keyProperty="id">
insert into t_phone(name,brand,model,price,ctime) values(#{name},#{brand},#{model},#{price},now())
</insert>
<select id="selectAll" resultType="com.feri.mybatis.entity.Phone">
select * from t_phone
</select>
</mapper>
6).在mybatis.xml中注册mapper映射文件
7)测试:
@Test
public void t1() throws IOException {
//1.创建工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(
Resources.getResourceAsStream("mybatis-config.xml"));
//2.获取 会话对象
SqlSession session=factory.openSession(true);
//3.获取接口的实现类对象
PhoneDao dao=session.getMapper(PhoneDao.class);
System.err.println("新增:"+dao.add(new Phone("苹果14Pro","苹果","14",8999.0)));
System.err.println("查询:"+dao.selectAll());
}
8)运行结果展示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dd6tdusz-1681711718719)(assets/1681691849554.png)]
验证验证缓存的一致性
1)测试:
public void t2() throws IOException {
//1.创建工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(
Resources.getResourceAsStream("mybatis-config.xml"));
//2.获取 会话对象
SqlSession session=factory.openSession(true);
//3.获取接口的实现类对象
PhoneDao dao=session.getMapper(PhoneDao.class);
System.err.println("查询1:"+dao.selectAll());
System.err.println("新增:"+dao.add(new Phone("摩托罗拉Edgpro","摩托","edg",3999.0)));
System.err.println("查询2:"+dao.selectAll());
}
2)运行结果展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9HkURfUv-1681711718720)(assets/1681691994782.png)]
2.二级缓存
二级缓存特点
二级缓存是把缓存的数据存储在SQLSessionFactory上面(对象内部)
二级缓存的数据,所有的session可以共用
二级缓存默认关闭,使用的需要配置
二级缓存实现步骤:
1.把要缓存的对象对应的类实现序列化接口
@Data
@NoArgsConstructor
public class Phone implements Serializable {
private Integer id;
private String name;
private String brand;
private String model;
private Double price;
private Date ctime;
public Phone(String name, String brand, String model, Double price) {
this.name = name;
this.brand = brand;
this.model = model;
this.price = price;
}
}
2.在mybatis-config中开启二级缓存
<settings>
<!-- 开启日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
3.在需要使用二级缓存的映射文件中实现配置
<!-- 二级缓存设置
cache 二级缓存
size属性:容量
eviction:策略,容量满的时候,改按照什么规则删除缓存数据 常用:1.LRU(最近最少使用原则) 2.FIFO(先进先出) 3.Soft(软引用) 4.Weak(弱引用) -->
<cache size="1024" eviction="LRU"></cache>
4.编写代码测试二级缓存
@Test
public void t4() throws IOException {
//1.创建工厂对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsStream("mybatis-config.xml"));
//2.获取 会话对象
SqlSession session1 = factory.openSession(true);
SqlSession session2 = factory.openSession(true);
//3.验证二级缓存
System.err.println("第一个会话:"+session1.getMapper(PhoneDao.class).selectAll());
session1.close();
System.err.println("第二个会话:"+session2.getMapper(PhoneDao.class).selectAll());
}
5.运行结果
更多推荐
已为社区贡献1条内容
所有评论(0)