今天的学习内容:
1.复习批量操作
2.代码生成器--使用(重点)
3.延迟加载(懒加载)
4.缓存:一级缓存和二级缓存
1、Mybatis中的延迟加载(补充重点)
问题:在一对多中,当我们有一个用户,它有100个订单。
在查询用户的时候,要不要把关联的订单查出来?
在查询订单的时候,要不要把关联的用户查出来?
解答:
在查询用户时,用户下的订单信息应该是,什么时候使用,什么时候查询的。
在查询订单时,订单的所属用户信息应该是随着订单查询时一起查询出来。
什么是延迟加载
在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)lazyloading
什么是立即加载
不管用不用,只要一调用方法,马上发起查询。
在对应的四种表关系中:一对多,多对一,一对一,多对多
一对多,多对多: 通常情况下我们都是采用延迟加载。
多对一,一对一: 通常情况下我们都是采用立即加载。
2、Mybatis中的缓存
什么是缓存
存在于内存中的临时数据。
为什么使用缓存
缓存原理:当执行了第一次查询以后,访问的数据会被放到缓存中;
当执行第二次查询的时候,它会先到缓存中查询是否有该数据,如果有就拿出来
减少和数据库的交互次数,提高执行效率。
什么样的数据能使用缓存,什么样的数据不能使用
适用于缓存:
经常查询并且不经常改变的。
数据的正确与否对最终结果影响不大的。
不适用于缓存:
经常改变的数据
数据的正确与否对最终结果影响很大的。
例如:商品的库存,银行的汇率,股市的牌价。
Mybatis中的一级缓存和二级缓存
一级缓存:
它指的是Mybatis中SqlSession对象的缓存。系统默认提供,不用设置和修改。
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中
查询是否有,有的话直接拿出来用,如果没有就再次访问数据库查询。
当SqlSession对象消失时,mybatis的一级缓存也就消失了。一级缓存是 SqlSession 范围的缓存,当调用SqlSession 的修改,添加,删除,commit(),close(),clearCache()等方法时,就会清空一级缓存。
二级缓存:
概念:由mybatis中的SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
SqlSessionFactory-->SqlSession
二级缓存的使用步骤:
第一步:让Mybatis框架支持二级缓存(在mybatis-config. xm1中配置)
<setting name="cacheEnabled" value="true"/>
第二步:让当前的映射文件支持二级缓存(在UserMapper.xml中配置)
<cache/>
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,
最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的
eviction属性:
LRU – 最近最少使用:移除最长时间不被使用的对象。(默认)FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
第三步:让当前的操作支持二级缓存(在select标签中配置 useCache="true")
对某一命名空间的语句,只会使用该命名空间的缓存进行缓存或刷新。
但你可能会想要在多个命名空间中共享相同的缓存配置和实例。
要实现这种需求,你可以使用 cache-ref 元素来引用另一个缓存。
<cache-ref namespace="com.someone.application.data.SomeMapper"/>
Mybatis 二级缓存脏读
1. 脏读的产生:
Mybatis的二级缓存是和命名空间绑定的,所以通常情况下每一个Mapper映射文件都有
自己的二级缓存,不同的mapper的二级缓存互不影响。这样的设计一不注意就会引起脏读,从而导致数据一致性的问题。引起脏读的操作通常发生在多表关联操作中,比如在两个不同的mapper中都涉及到同一个表的增删改查操作,当其中一个mapper对这张表进行查询操作,此时另一个mapper进行了更新操作刷新缓存,然后第一个mapper又查询了一次,那么这次查询出的数据是脏数据。出现脏读的原因是他们的操作的缓存并不是同一个。
2. 脏读的避免:
1. mapper中的操作以单表操作为主,避免在关联操作中使用mapper
2. 在关联操作的mapper中使用参照缓存
配置:
Mapper接口和XML配置使用的是同一个命名空间。因此他们只能使用同一个缓存。
<!--那么在XML中只能使用参照缓存-->
<mapper namespace="com.mybatis.mapper.UserMapper">
<cache-ref namespace="com.mybatis.mapper.OrdersMapper"/>
<!—其他配置-->
</mapper>
二级缓存的使用条件:
参照缓存可以解决关联较少的情况,如果有几十个表且关联复杂时,使用参照缓存意义不大。
因此使用二级缓存需要满足一定的条件:
1. 以查询为主的应用中,只有尽可能少的新增、删除和更新操作。
2. 查询业务绝大多数都是对单表进行操作,由于很少存在互相关联的情况,因此不会出现脏数据。
3. 可以按业务划分对表进行分组时,如果关联的表比较少,可以通过参照缓存进行配置。