一:什么是缓存?
缓存(cache),数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据取出,放置在 缓冲区中,应用程序从缓冲区读取数据。
缓存的特点:
数据存放在内存中,可以快速访问并使用
缓存的缺点:
数据无法得到更新
缓存有两种说法,即命中和未命中。
命中指的是在缓存中找到了需要的数据,而未命中指的是没有找到需要的数据,未命中则需要到数据库中继续寻找。
缓存的作用:
减少 Java Application 与数 据库的交互次数,从而提升程 序的运行效率;
适合使用缓存:
经常查询并且不经常改变的
数据的正确与否对最终结果影响不大的
比如:一个公司的介绍,新闻等
不是适用于缓存:
经常改变的数据
数据的正确与否对最终结果影响很大
比如商品的库存,股市的牌价等
二:立即加载和延迟加载
立即加载
即不管信息有没有用,只要调用,拿上发起查询并加载信息
例如:当我们查询学生信息时,就需要知道学生在哪个班级,所以就要立即查询班级信息
通常当一对一 或 多对一 的时候需要立即加载
延迟加载
当真正使用数据的时候才发起查询,不用的时候不查询,按需加载(也叫懒加载)
例如: 在查询班级信息,每个班级都会有很多的学生(假如每个班有100个学生),如果我们只是查看 班级信息,但是学生对象也会加载到内存中,会造成浪费。 所以我门需要进行懒加载,当确实需要查看班级中的学生信息,我门在进行加载班级中的学生信息。
通常:一对多 或 多对多 的时候需要延迟加载
配置方式
立即加载时默认的,所以要配置懒加载就需要修改一下
三:一级缓存
什么是一级缓存:
一级缓存是默认开启的,只能对同一个SqlSession对象而言
Student stu1 = sm.findStudentBysid(1);
Student stu2 = sm.findStudentBysid(1);
System.out.println(stu1 == stu2);
//结果为true
Student stu1 = sm.findStudentBysid(1);
sqlSession.clearCache();
Student stu2 = sm.findStudentBysid(1);
System.out.println(stu1 == stu2);
DBUtil.sqlSessionClose(sqlSession)
//结果为false
因为这里的sqlSession被关掉了一次,又重新建立的sqlSession和之前的不是同一个,缓存被删掉重新建立了一个,所以“ == ”的结果是false。
注意:当调用sqlsession的修改,添加,删除,commit(),close() 等方法是, 就会清空一级缓存
一级缓存的配置
localCacheScope:表示配置一级缓存
SESSION 默认是session级别的缓存
STATEMENT statement级别的缓存
一级缓存失效的情况:
不同的SqlSession对应不同的一级缓存
同一个SqlSession单查询条件不同
同一个SqlSession两次查询期间执行了任何一次增删改操作
同一个SqlSession两次查询期间手动进行了清空缓存
四:二级缓存
二级缓存说明
在同一个sql工厂下的都是二级缓存,但是注意工厂在项目之处成立,并在项目结束时结束,所以项目运行中是无法关闭和更新数据的
配置步骤
第一种:
第二种(注释方式):
1、在mybatis的SqlMapConfig.xml中配置
2、在接口的定义上面直接使用@CacheNamespace并将blocking设置为true
二级缓存的特点
Mybatis 的二级缓存相对于一级缓存来说, 实现了缓存数据的共享,可控性也更强;
极大可能会出现错误数据,有设计上的缺陷,安全使用的条件比较苛刻;
分布式环境下,必然会出现读取到错误数据,所以不推荐使用。