MyBatis总结八:缓存介绍(一级缓存,二级缓存)
一级缓存:session级别缓存,作用于当前会话。
二级缓存:SessionFactory级别缓存,作用于整个SessionFactory,多个会话之间可以共享缓存
一级缓存:
-
mybatis的一级缓存默认就是开启的,并且无法关闭。
-
mybatis的一级缓存作用域是当前session,一次openSession()后,如果相同的statement和相同参数,则不进行查询而是从缓存命中并且返回,如果没有命中则查询数据库。
-
任何的增删改操作都会导致缓存被清空
-
缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回
测试一级缓存:
@Test public void testLevelOneCache() throws Exception { User user1 = mapper.getUserById(1); System.out.println(user1); System.out.println("---------------------------"); User user2 = mapper.getUserById(1); System.out.println(user2); }
输出结果:
我们可以看出来 第二次查询的时候 并没有执行sql语句 而是从缓存中读取的。
二级缓存:
-
二级缓存需要手动开启,开启的方式是在Mapper.xml中添加标签:<cache/>
-
二级缓存的作用域是整个SessionFactory,并且是同一个Mapper中,如果namespace、statement和SQL参数一致,则缓存命中
-
映射语句文件中的所有select语句将会被缓存。
-
映射语句文件中的所有insert,update和delete语句会刷新缓存。
-
缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
-
缓存会根据指定的时间间隔来刷新。
-
缓存默认会存储1024个对象
开启二级缓存:
<mapper namespace="com.zy.mapper.UserMapper"> <!--开启二级缓存--> <cache />
测试二级缓存:
注意这里有个前提条件,就是User类必须继承Serializable接口
public class UserMapperTest { UserMapper mapper; SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void setUp() throws Exception { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); sqlSession = sqlSessionFactory.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); } @Test public void testLevelTwoCache() { // 一次会话中 // 1 第1次查询 User user1 = mapper.getUserById(1); System.out.println(user1); // 关闭session sqlSession.close(); // 重新开启session sqlSession = sqlSessionFactory.openSession(true); // 重新获取mapper mapper = sqlSession.getMapper(UserMapper.class); System.out.println("------------------------------------------"); // 2 第2次查询 User user2 = mapper.getUserById(1); System.out.println(user2); } }
cache标签常用属性:
<cache eviction="FIFO" <!--回收策略为先进先出--> flushInterval="60000" <!--自动刷新时间60s--> size="512" <!--最多缓存512个引用对象--> readOnly="true"/> <!--只读-->
可用的收回策略有:
-
LRU
– 最近最少使用的:移除最长时间不被使用的对象。 -
FIFO
– 先进先出:按对象进入缓存的顺序来移除它们。 -
SOFT
– 软引用:移除基于垃圾回收器状态和软引用规则的对象。 -
WEAK
– 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
默认的是 LRU。
flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是 1024。
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。
另外mybatis-config.xml中的settings中有个参数叫做cacheEnabled,默认为true表示开启缓存,如果设置为flase所有的缓存将消失。