MyBatis 缓存
1、缓存(Cache)简介
- 缓存的概念
存在内存中的临时数据;将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
- 为什么使用缓存?
减少和用户和数据库的交互次数,减少系统的系统内存和资源的开销,极大地提高数据库查询的效率。
- 什么样的数据可以使用缓存?
经常查询并且不经常修改的数据。
2、MyBatis 缓存
- MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
- MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存。
默认情况下:一级缓存开启,SqlSession 级别的缓存,也叫本地缓存。
二级缓存需要手动开启和配置,基于namespace级别的缓存。MyBatis中定义了缓存接口,我们可以通过Cache接口来实现二级缓存。
3、一级缓存
一级缓存也叫作本地缓存,是SqlSession层面实现的缓存;
实现: 和数据库同一次会话期间查询到的用户数据会放在本地缓存中;以后如果需要获取相同的数据,直接就从缓存中获取,没必要再去查询数据库。
测试:
数据库:
实体类:
package com.zyh.pojo;
import lombok.Data;
@Data
public class User {
private int id;
private String name;
private String pwd;
}
接口:
package com.zyh.mapping;
import com.zyh.pojo.User;
import org.apache.ibatis.annotations.*;
import javax.naming.Name;
import java.util.List;
/**
* 使用注解进行开发
*/
public interface UserMapper {
//根据id查询用户
User getUserById(@Param("id") int id);
}
接口的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">
<!--namespace的作用:和你编写的持久层的接口关联起来-->
<mapper namespace="com.zyh.mapping.UserMapper">
<select id="getUserById" parameterType="int" resultType="user">
select * from user where id=#{id}
</select>
</mapper>
测试:
package com.zyh.mapping;
import com.zyh.pojo.User;
import com.zyh.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
public class MyTest {
@Test
public void test1(){
SqlSession session = MyBatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user1 = mapper.getUserById(1);
System.out.println(user1);
User user2 = mapper.getUserById(1);
System.out.println(user2);
System.out.println(user1 == user2);
session.close();
}
}
执行结果:
我们可以看到SQL只执行了一次,在这一次Sqlsession会话中。
可能会导致缓存失效的情况:
- 进行数据增删改的时候;
- 查询不同的数据
- 手动清除缓存
4、二级缓存
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存。
- 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
- 工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
- 新的会话查询信息,就可以从二级缓存中获取内容;
- 不同的mapper查出的数据会放在自己对应的缓存(map)中。
开启二级缓存的步骤:
- 开启全局缓存
<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
- 在要使用二级缓存的Mapper中开启
<!--在当前Mapper.xml中使用二级缓存-->
<cache/>
- 对应的实体类实现
Serializable
接口
测试:
SQL语句执行一次,存在缓存。