前言
将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能。
一级缓存
流程:用户发起一条查询指令,查询某条数据,sqlsession先去缓存中查找是否有这条数据,如果有,则直接读取缓存中的数据,如果没有,则从数据库中查找,然后放入当前sqlsession对象的一级缓存中,在将数据返回给用户
对应关系:每个sqlsession对象都对应一个相应的一级缓存,不同的sqlsession的一级缓存互不影响
数据结构:在每个sqlsession对象中都有一个HashMap集合来存储缓存数据,以键值对的形式存数据
清空时机:在两次查询之间,使用了增删改任意一个指令,会自动清空缓存;在两次查询之间手动清空了缓存。
生命周期:一级缓存的生命周期与sqlsession一致
可能出现的问题:当sqlsexxion1对象进行了一次查询操作且没有清理缓存时,sqlsession2对象对1对象所查数据进行了修改并提交,则此时1对象查询的数据结果任然是缓存中的旧数据,此时就对应上了,mysql中事务的默认隔离级别可重复读
总结:一级缓存存的内容是所查询内容解析后的javabean实现类对象的地址,MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存
二级缓存
流程:每当一个sqlsession在做commit操作的时候,就会清空一级缓存,将一级缓存的内容刷到二级缓存中。 一个SQL执行的时候,会先判断二级缓存中是否存在缓存,没有才会去检查一级缓存。
开启条件:二级缓存默认是不开启的,需要手动开启二级缓存,实现二级缓存的时候,MyBatis要求返回的javabean实现类必须是可序列化的。
(1)第一种方式:在主配置文件中的
<settings>
<setting name = "cacheEnabled" value = "true" />
</settings>
在mapper的xml文件中添加
<cache/>
(2) 第二种方式:在mapper接口中以注解的形式开启
区别是什么
(1)作用域不同,一级缓存作用域是当前sqlsession对象,二级缓存作用域是当前sqlsessionFactory工厂所生产的所有sqlsession对象
(2)开启方式不同,一级缓存默认开启,二级缓存默认关闭,需要手动开启
(3)存储类型不同,一级缓存存的是所查数据结果映射成javabean的实现类对象地址值,二级缓存存的是所查数据结果映射成javabean的实现类对象序列化后的properties文件
(4)存储位置不同,一级缓存在内存中,二级缓存则将数据写入磁盘