[MyBatis]关于缓存

一级缓存(本地缓存)

默认情况下被一直开启,从一个Mapper查询出来后放入本地,一个会话内有效,比如对象01发出一个sql,对象02也是同一个sql,只会发一个sql查询,对象01和02测试相等的时候是true,但是不同的mapper即使查询的语句一样,一级缓存都是会失效的。还有的情况是两次mapper是同一个sql也是同一个,但是中途执行了别的增删改的sql,数据库发生了改变,也会使得对象false

二级缓存(全局缓存)

本次讨论的重点,基于namespace级别

一级缓存的会话被关闭就会保存到二级缓存中

 

配置

在mybatis配置文件里加入

 
        

在需要配置缓存的mapper.xml里配置

【blocking】若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

【flushInterval】缓存刷新间隔,默认不清空,单位为毫秒值

【eviction】缓存的回收策略

[LRU]默认 最近最少使用,移除最长时间不被使用的对象

[FIFO]-先进先出

[SOFT]-软引用,移除基于垃圾回收器状态和软引用规则的对象

[WEAK]-弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象

【readOnly】是否只读[false][true]

【size】缓存存放多少个元素

【type】指定自定义的缓存的全类名,实现过cache接口的类

在指定mapper.xml里(注意这个是模板,如果有的字段是空的,要删掉,不然会报错的。)




    
    

POJO对象都要实现序列化接口

public class Person implements Serializable {

 private Integer pId;
 private String pName;//当和表里的列名不一致的时候,查询语句应该起别名
 //p_Name(原表里的列名) pname别名
 private String email;
 private Department dept;

测试

 public void test7() throws IOException {
  start();

  SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
  PersonMapperPlus mapper1 = sqlSession1.getMapper(PersonMapperPlus.class);
  Person p1 = mapper1.getPersonById(1);
  System.out.println(p1);
  sqlSession1.close();


  SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
  PersonMapperPlus mapper2 = sqlSession2.getMapper(PersonMapperPlus.class);
  Person p2 = mapper2.getPersonById(1);
  System.out.println(p1);
  sqlSession2.close();

  System.out.println(p1==p2);

  sqlSession.close();
 }

只有一条sql

[MyBatis]关于缓存_第1张图片

如果不用二级缓存,就会产生两条sql

[MyBatis]关于缓存_第2张图片

select标签里的【useCache="true"】

对单个标签里二级缓存有效,注意每个增删改标签里的【flushCache="true"】为默认

并且对一二级缓存都有效,所以每个对数据库的改变后都会重新发送新的sql

其他:

sqlssion.clearCache()对当前会话有效,而对二级缓存无关

localCacheScope本地缓存作用域

-【SESSION】默认,当前会话的所有数据保存在当前会话中

-【STATMENT】可以禁用

 

其实每个缓存约等于一个Map

 

 

 

你可能感兴趣的:(MyBatis)