Mybatis有一级缓存和二级缓存
一级缓存
一级缓存的作用域为一个session的存在周期 即session关闭 缓存自动清除 一级缓存是默认开启的
@Test
public void getUser(){
SqlSession session = MybatisUtils.getsession();
Usermapper mapper = session.getMapper(Usermapper.class);
User user1 = mapper.getUser(1);
System.out.println(user1);
System.out.println("===========================");
User user2 = mapper.getUser(1);
System.out.println(user2);
session.close();
}
从上图我们可以看出 在一个session周期中我们对同一个人执行了两次查询 但是只执行了一次sql语句 因为第一次执行后 已经把缓存存到了一级缓存中 我们第二次访问可以直接调用
@Test
public void getUser(){
SqlSession session = MybatisUtils.getsession();
Usermapper mapper = session.getMapper(Usermapper.class);
User user1 = mapper.getUser(1);
System.out.println(user1);
System.out.println("============================");
HashMap<String, Object> map = new HashMap<>();
map.put("name","liupeng");
map.put("id",1);
mapper.updateUser(map);
System.out.println("===========================");
User user2 = mapper.getUser(1);
System.out.println(user2);
session.close();
}
而当我们在两次查询之间 执行了一次更新操作之后 当再去查询时 缓存已经清除 于是又执行了一遍sql
缓存失效的表现
1、不同的session
2、不同的查询语句
3、当该条记录查询后执行过更新、删除、增加操作时 缓存会自动清除
4、不同的mapper映射文件
二级缓存
二级缓存的作用域是一个namespace 即一个mapper的映射文件 ,使用二级缓存需要我们配置
首先在核心配置文件中设置
<!--设置缓存开启-->
<setting name="cacheEnabled" value="true"/>
然后在映射文件中设置即可
<cache/>
然后将实体类序列化
public class User implements Serializable
测试
@Test
public void getUser(){
SqlSession session = MybatisUtils.getsession();
Usermapper mapper = session.getMapper(Usermapper.class);
User user1 = mapper.getUser(1);
System.out.println(user1);
session.close();
/* System.out.println("============================");
HashMap<String, Object> map = new HashMap<>();
map.put("name","liupeng");
map.put("id",1);
mapper.updateUser(map);*/
System.out.println("===========================");
SqlSession session1 = MybatisUtils.getsession();
Usermapper mapper1 = session1.getMapper(Usermapper.class);
User user2 = mapper1.getUser(1);
System.out.println(user2);
session1.close();
}
由于我们设置了二级缓存 因此当第一个session关闭时 它将自己的缓存放到了二级缓存里 当我们重新创建session执行相同的语句时,它就自动在二级缓存里找到了结果
注意下面这句话
//第一次创建session时 它创建了连接池
Created connection 396283472.
//第二次创建session时 它直接从池子里找到了我们之前查询的结果
Returned connection 396283472 to pool.
小结