MyBatis缓存
2020-06-26 本文已影响0人
凡哥爱丽姐
正如大多数持久化框架一样,MyBatis提供了对一级缓存和二级缓存的支持。
1、一级缓存
一级缓存作用范围是sqlSession域内,当sqlSession flush或者close之后,该sqlSession中所有的cache就会被清空,一般是自动开启的。
下面我们以一个查询所有用户为例(添加驱动的jar包、创建MyBatis的核心配置文件mybatis-config.xml以及log4j我们就省略了,大家可以按照之前的教程自行配置)
1.1、创建User实体类
package com.fan.entity;
public class User {
private Integer id;
private String name;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
1.2、创建UserDao接口类
package com.fan.dao;
import com.fan.entity.User;
import java.util.List;
public interface UserDao {
//查询所有用户
public List<User> findAllUser();
}
1.3、添加mapper文件
<mapper namespace="com.fan.dao.UserDao">
<select id="findAllUser" resultType="com.fan.entity.User">
select * from users
</select>
</mapper>
1.4、添加测试类
import com.fan.dao.UserDao;
import com.fan.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
Reader resourceAsReader=null;
SqlSession sqlSession=null;
try {
resourceAsReader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSession = new SqlSessionFactoryBuilder().build(resourceAsReader).openSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> allUser = mapper.findAllUser();
for (User user:allUser) {
System.out.println(user.getName());
}
System.out.println("---------------------------------------------");
UserDao mapper1 = sqlSession.getMapper(UserDao.class);
List<User> allUser1 = mapper1.findAllUser();
for (User user1:allUser) {
System.out.println(user1.getName());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(sqlSession!=null){
sqlSession.close();
}
if(resourceAsReader!=null){
try {
resourceAsReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
测试结果如下图所示(只调用了一次查询语句):
测试结果1.5、一级缓存失效情况
1、查询不同的东西
2、增删改操作,可能会改变原来的数据,所以必定会刷新缓存!
3、查询不同的Mapper.xml
4、手动清理缓存
2、二级缓存
定义:
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存。
基于namespace级别缓存,一个名称空间,对应一个二级缓存。
工作机制:
1、一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中。
2、如果当前会话关闭了,这个会话对应一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中。
3、新的会话查询信息,就可以从二级缓存中获取内容。
4、不同的mapper查出数据会放在自己对应的缓存中。
2.1、在映射文件mapper设置缓存
<mapper namespace="接口路径">
<cache eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true">
</cache>
</mapper>
说明:
eviction: 二级缓存中,缓存的对象从缓存中移除的策略(上面FIFO的回收策略为先进先出)
flushInterval: 刷新缓存的事件间隔
size: 缓存对象的个数
readOnly: 是否是只读的
2.2、创建User实体类
package com.fan.entity;
import java.io.Serializable;
public class User implements Serializable {
private Integer id;
private String name;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
2.3、创建UserDao接口类
package com.fan.dao;
import com.fan.entity.User;
import java.util.List;
public interface UserDao {
//查询所有用户
public List<User> findAllUser();
}
2.4、mapper文件中加入缓存cache的配置如下
<mapper namespace="com.fan.dao.UserDao">
<cache eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true">
</cache>
<select id="findAllUser" resultType="com.fan.entity.User">
select * from users
</select>
</mapper>
2.5、测试类
import com.fan.dao.UserDao;
import com.fan.entity.User;
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.IOException;
import java.io.Reader;
import java.util.List;
public class Test1 {
public static void main(String[] args) throws IOException {
Reader resourceAsReader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsReader);
SqlSession sqlSession1 = factory.openSession();
UserDao mapper = sqlSession1.getMapper(UserDao.class);
List<User> allUser = mapper.findAllUser();
for (User user:allUser) {
System.out.println(user.getName());
}
sqlSession1.close();
System.out.println("---------------------------------------------");
SqlSession sqlSession2 = factory.openSession();
UserDao mapper1 = sqlSession2.getMapper(UserDao.class);
List<User> allUser1 = mapper1.findAllUser();
for (User user1:allUser1) {
System.out.println(user1.getName());
sqlSession2.close();
}
}
}