`

Mybatis延迟加载和查询缓存

阅读更多

Mybatis延迟加载和查询缓存

 

一、延迟加载

  resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。

  延迟加载:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

在mybatis核心配置文件中配置:

lazyLoadingEnabled、aggressiveLazyLoading

设置项

描述

允许值

默认值

lazyLoadingEnabled

全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。

true | false

false

aggressiveLazyLoading

当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。

true | false

true

复制代码
<settings>

      <setting name="lazyLoadingEnabled" value="true"/>

      <setting name="aggressiveLazyLoading" value="false"/>

</settings>
复制代码

  场合:

         当只有部分记录需要关联查询其它信息时,此时可按需延迟加载,需要关联查询时再向数据库发出sql,以提高数据库性能。

         当全部需要关联查询信息时,此时不用延迟加载,直接将关联查询信息全部返回即可,可使用resultType或resultMap完成映射。

 

二、查询缓存

  Mybatis提供查询缓存,用于减轻数据压力,提高数据库压力。

  Mybatis提供一级缓存和二级缓存。

  

  在操作数据库时需要构造SqlSession对象,在对象中有一个数据结构(HashMap)用于缓存数据。

  不同的SqlSession之间的缓存数据区域是互相不影响的。

  Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

   Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

  1、一级缓存

  

  第一次发起查询,先去找缓存中是否有id为1的用户信息,如果没有,从数据库中查询用户信息。

  得到用户信息,将用户信息存储到一级缓存中。

  第二次发起查询用户id为1的用户信息,先去缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

  如果SqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存。目的是为了让缓存中存储的是最新的信息,避免脏读。

  Mybatis默认支持一级缓存,不需要在配置文件中配置。

  Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象。

  应用场景:

  

  2、二级缓存

  

  SqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。

  SqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。

  二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。

每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。

  Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象

  sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

  开启二级缓存

  在核心配置文件SqlMapConfig.xml中加入

<setting name="cacheEnabled" value="true"/>
 

描述

允许值

默认值

cacheEnabled

对在此配置文件下的所有cache 进行全局性开/关设置。

true false

true


要在你的Mapper映射文件中添加一行:  <cache /> ,表示此mapper开启二级缓存。

  二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。

  为了将缓存数据取出执行反序列化,因为二级缓存存储介质多种多样,不一定在内存。

  禁用二级缓存:

  在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

  <select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

  刷新缓存(就是清空缓存)

  设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。

  <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

  应用场景

  对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。

      实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。

  局限性

  mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。

分享到:
评论

相关推荐

    Mybatis延迟加载和缓存

    Mybatis 的缓存机制可以分为一级缓存和二级缓存。一级缓存是 Session 级别的缓存,它是默认开启的。当我们在一个 Session 中执行 SQL 查询并获取结果后,这些结果会被存储在内存中。如果在同一个 Session 内再次执行...

    Mybatis延迟加载和缓存(基于XML配置).zip

    Mybatis的缓存机制可以分为一级缓存和二级缓存。一级缓存在SqlSession级别,同一个SqlSession内的多次相同查询会复用第一次查询的结果,避免重复的数据库访问。而二级缓存则在Mapper级别,多个SqlSession之间可以...

    MyBatis懒加载(延迟加载)

    并设置`lazyLoadingEnabled=true`和`fetchType=lazy`,MyBatis会在运行时生成一个代理对象,当你试图访问被标记为懒加载的属性时,才会触发实际的SQL查询。 3. **association标签**:在描述中提到的"association...

    mybatis3--延迟加载,缓存

    MyBatis 提供了两种级别的缓存:一级缓存和二级缓存。 1. **一级缓存(Local Cache)**:一级缓存是 SqlSession 级别的缓存,同一个 SqlSession 内的多次查询,如果查询的是相同的 SQL,MyBatis 会直接从缓存中获取...

    mybatis的延迟加载,全局加载及一级缓存及二级缓存

    mybatis的延迟加载,全局加载及一级缓存及二级缓存, 包括完整的笔记及代码演示, 实操性强,讲解充分

    缓存处理-mybatis层

    首先,我们要理解MyBatis的缓存分为一级缓存和二级缓存。一级缓存是SqlSession级别的,也被称为本地缓存,它存储在SqlSession对象内部。当我们在同一个SqlSession内执行相同的SQL语句时,MyBatis会优先从一级缓存中...

    Mybatis(dao)缓存|mybatis+redis(dao+service)缓存验证

    Mybatis提供了一级缓存和二级缓存两种缓存机制,这两种缓存机制有助于提高数据访问的效率。 **1.1 一级缓存** 一级缓存是在同一个`SqlSession`生命周期内的缓存机制,它基于Per SqlSession存储。当同一个`...

    mybatis 的高级关联查询源码

    - 使用 `lazyLoadingEnabled` 属性可实现延迟加载,只有当访问到关联对象时才执行子查询,提高初次加载速度。 - `fetchSize` 设置可以控制每次从数据库读取的数据量,避免一次性加载大量数据导致内存溢出。 - `...

    定时完成Springmvc+mybatis+redis完成二级缓存

    **Redis** 是一个高性能的键值对存储系统,常用于实现缓存和消息队列等场景。在本项目中,Redis被用作二级缓存的存储介质,由于其快速的读写性能和丰富的数据结构,能有效地提升数据获取速度。 **Quartz** 是一个...

    mybatis从入门到精通(第一节)

    • 延迟加载(侵入式延迟加载、深度延迟加载) • 关联查询(一对一、一对映射) • 逆向工程 • PageHelper分页插件 • 注解开发 主键返回(mybatis的自增主键或者非自增主键) • 批量查询 • 动态传参 • 查询...

    MyBatis3.2.4完全自学手册

    MyBatis支持一级缓存和二级缓存。一级缓存默认开启,用于缓存同一个SQLSession内的查询结果;二级缓存则需要显式启用,并可以跨SQLSession共享查询结果。 示例: ```xml ... ``` #### 十一、整合Spring ...

    Mybatis第四天

    在Mybatis的学习过程中,第四天通常会涵盖一些关键特性,如延迟加载、一级缓存、二级缓存,以及如何利用注解进行单表和多表的CRUD操作。接下来,我们将详细探讨这些知识点。 首先,**延迟加载(Lazy Loading)** 是一...

    MyBatis2.rar

    MyBatis提供了一级缓存和二级缓存。一级缓存是SqlSession级别的,同一个SqlSession内的多次相同查询将直接从内存中获取结果,无需再次执行SQL。二级缓存则是Mapper级别的,它可以跨SqlSession共享数据,进一步提升...

    mybatis框架的使用

    Mybatis 框架的使用 Mybatis 是一个基于 Java 的...Mybatis 提供了多种机制来提高应用程序的性能,包括延迟加载、按需加载、动态 SQL 和缓存机制。Mybatis 的缓存机制可以与 Ehcache 集成,以提供更加强大的缓存服务。

    《MyBatis 基础笔记》源代码

    以上内容只是MyBatis基础部分的概述,实际使用中,MyBatis还有更多高级特性和最佳实践,如结果映射的复杂性、延迟加载、插件机制等,都需要深入学习和理解。通过阅读《MyBatis 基础笔记》的源代码,你可以更深入地...

    Mybatis注解与 延时加载(懒加载) 二级缓存注解配置

    注解: 1.@Insert:实现新增。 2.@Update:实现更新。 3.@Delete:实现删除。 4.@Select:实现查询。...示例 二 多对一 延时加载(懒加载) 根据id查询员工及其员工的部门信息 1.1 User类结构 2.注解配置

    mybatis开发jar包

    10. **延迟加载**:MyBatis的延迟加载功能可以在真正需要数据时才进行加载,提高了应用的响应速度。 以上就是关于MyBatis的一些核心知识点,这些内容涵盖了MyBatis的基本使用和高级特性,有助于开发者深入理解和...

Global site tag (gtag.js) - Google Analytics