目录
MyBatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
缓存
缓存是存在内存中的临时数据。将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。使用缓存能够减少和数据库的交互次数,减少系统开销,提高系统效率。经常查询并且不经常改变的数据能够使用缓存。
MyBatis缓存
- MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
- MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存,默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)。
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口定义二级缓存。
MyBatis缓存的术语
命中
需要查询的数据在缓存中能找到结果,不再去数据库查询。
未命中
需要查询的数据在缓存中未能找到结果,重新去数据库查询。
MyBatis缓存的适用性
适合使用缓存:
经常查询并且不经常改变的 数据的正确与否对最终结果影响不大的
比如:一个公司的介绍,新闻等
不适合使用缓存:
经常改变的数据 数据的正确与否对最终结果影响很大
比如:商品的库存,股市的牌价等
MyBatis缓存的分类
一级缓存
MyBatis的一级缓存是SqlSession级别的缓存,当在同一个SqlSession中执行两次相同的SQL语句时,会将第一次执行查询的数据存入一级缓存中,第二次查询时会从缓存中获取数据,而不用再去数据库查询,从而提高查询性能。
一级缓存的执行流程
- 对于某个SelectStatement,根据该Statement生成key;
- 判断在LocalCache中,该key是否用对应的数据存在;
- 如果命中,则跳过查询数据库,继续往下走;
- 如果没命中,去数据库中查询数据,得到查询结果;
- 将key和查询到的结果作为 key 和 value,放入Local Cache 中;
- 将查询结果返回;
- 判断缓存级别是否为 STATEMENT 级别,如果是的话,清空本地缓存;
一级缓存的失效情况
- 不同SqlSession时 对应不同的一级缓存
- 同一个SqlSession 但单查询条件不同时
- 同一个SqlSession 两次查询期间执行了任何一次增删改操作时
- 同一个SqlSession 两次查询期间手动清空了缓存时
一级缓存的生命周期
- MyBatis在开启一个数据库会话时,会创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象。Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。
- 如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用。
- 如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用。
- SqlSession中执行了任何一个update操作(update()、delete()、insert()),都会清空PerpetualCache对象的数据,但是该对象可以继续使用。
二级缓存
Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存。
二级缓存的的配置(常规)
1.在mybatis的sqlMapConfig.xml 中配置
2.在mybatis的sqlmap中配置(mapper.xml中配置)
3.在使用的操作中配置(在select标签中配置)
二级缓存的的配置(注解)
1.在mybatis的sqlMapConfig.xml 中配置
2.在接口的定义上面直接使用@CacheNamespace 并将blocking设置为true
二级缓存总结
- Mybatis的二级缓存相对于一级缓存来说,实现了缓存数据的共享,可控性也更强;
- 极大可能会出现错误数据,有设计上的缺陷,安全使用的条件比较苛刻;
- 分布式环境下,必然会出现读取到错误数据,所以不推荐使用。
自定义缓存
实现 org. apache. ibatis. cache. Cache 接口自定义缓存;
引入 Redis 等第三方内存库 作为 MyBatis 缓存。
一级缓存和二级缓存的区别
一级缓存是指SqlSession级别的缓存,是默认开启的。一级缓存缓存的是对象,当SqlSession提交,关闭以及其它的更新数据库的操作发生后,一级缓存就会清空。在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。以后每次相同的查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。
二级缓存是Mapper级别的缓存,需要手动开启。第一次调用Mapper下的SQL去查询用户的信息,查询到的信息会存放代该Mapper对应的二级缓存区域。 第二次调用namespace下的Mapper映射文件中,相同的SQL去查询用户信息,会去对应的二级缓存内取结果。