什么是缓存:
存在内存中的临时数据。
将用户经常查询的数据放在缓存(内存中),用户去查询数据就不用从磁盘上查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
为什么使用缓存?
减少和数据库的交互次数,减少系统开销,提高系统效率。
什么样的数据能使用缓存?
经常查询并不经常改变的数据。
Mybatis中的缓存:系统默认定义了两级缓存:一级缓存和二级缓存
- 默认情况下,只有一级缓存开启,(SqlSession级别的缓存,也称为本地缓存)
- 二级缓存需要手动开启和配置,基于namespace级别的缓存,也就是一个mapper一个缓存。
- 为了提高扩展性,Mybatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存。
Cache接口
public interface Cache {
String getId();
void putObject(Object var1, Object var2);
Object getObject(Object var1);
Object removeObject(Object var1);
void clear();
int getSize();
default ReadWriteLock getReadWriteLock() {
return null;
}
}
以及它的各种实现类,也就是缓存策略
Lru:最近最少使用
fifo:先进先出
梦回操作系统哈哈哈哈
一级缓存也叫本地缓存
与数据库同一次会话期间查询到的数据会放到本地缓存中。
如果以后需要获取相同的数据,直接从缓存中拿,没必要再去查数据库。
来一个例子:
@Test
public void test02(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> student = mapper.getStudent();
System.out.println(student);
System.out.println("===============================");
List<Student> student1 = mapper.getStudent();
System.out.println(student1);
System.out.println(student == student1);
sqlSession.close();
}
这里一个语句执行了两次,
但在结果中可以明显的看到只执行了一次SQL语句,第二次就是直接从缓存中得到的。
并且得到的两个对象是同一个。
而如果语句不一样就没有缓存
@Test
public void test02(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student studentById = mapper.getStudentById(1);
System.out.println(studentById);
System.out.println("===================================");
Student studentById1 = mapper.getStudentById(2);
System.out.println(studentById1);
sqlSession.close();
}
查询的时候必须执行两次SQL才行。
还有一些情况会让缓存失效
比如增删改
@Test
public void test02(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student studentById = mapper.getStudentById(1);
System.out.println(studentById);
mapper.add(new Student(100,"yf",1));
System.out.println("===================================");
Student studentById1 = mapper.getStudentById(1);
System.out.println(studentById1);
System.out.println(studentById == studentById1);
sqlSession.close();
}
在增加一个数据之后再查询同样的数据
需要查询两次,并且两次得到的对象是不一样的。
为什么会这样?
缓存可以看成是数据的临时存储,
数据发生变化,那缓存肯定就是要刷新的,不然数据就不一致了。
sqlSession中有一个方法
sqlSession.clearCache();
可以手动清理缓存。
一级缓存默认是开启的,也就是在一次sqlSession中有效,也就是从拿到sqlSession到关闭的期间。