前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis关联(嵌套)查询与延迟加载

Mybatis关联(嵌套)查询与延迟加载

作者头像
向着百万年薪努力的小赵
发布2022-12-02 10:51:27
3650
发布2022-12-02 10:51:27
举报
文章被收录于专栏:小赵的Java学习

我们在查询业务数据的时候经常会遇到关联查询的情况,比如查询员工就会关联部门(一对一),查询学生成绩就会关联课程(一对一),查询订单就会关联商品(一对多),等等。

在这里插入图片描述
在这里插入图片描述

映射结果有两个标签,一个是,一个是。 是select标签的一个属性,适用于返回JDK类型(比如Integer. String等等)和实体类。这种情况下结果集的列和实体类的属性可以直接映射。如果返回的字段无法直接映射,就要用来建立映射关系。 对于关联查询的这种情况,通常不能用来映射。用映射,要么就是修改dto (Data Transfer Object),在里面增加字段,这个会导致增加很多无关的字段。要么就是引用关联的对象,比如Blog里面包含了一个Author对象(多对一),这种情况下就要用到关联查询(association,或者嵌套查询),MyBatis 可以帮我们自动做结果的映射。

association和collection的区别: association是用于一对一和多对一,而collection是用于一对多的关系。 一对一的关联查询有两种配置方式:

嵌套结果

代码语言:javascript
复制
    <!-- 根据文章查询作者,一对一查询的结果,嵌套查询 -->
    <resultMap id="BlogWithAuthorResultMap" type="com.gupaoedu.domain.associate.BlogAndAuthor">
        <id column="bid" property="bid" jdbcType="INTEGER"/>
        <result column="name" property="name" jdbcType="VARCHAR"/>
        <!-- 联合查询,将author的属性映射到ResultMap -->
        <association property="author" javaType="com.gupaoedu.domain.Author">
            <id column="author_id" property="authorId"/>
            <result column="author_name" property="authorName"/>
        </association>
    </resultMap>

嵌套查询

代码语言:javascript
复制
    <!-- 另一种联合查询(一对一)的实现,但是这种方式有“N+1”的问题 -->
    <resultMap id="BlogWithAuthorQueryMap" type="com.gupaoedu.domain.associate.BlogAndAuthor">
        <id column="bid" property="bid" jdbcType="INTEGER"/>
        <result column="name" property="name" jdbcType="VARCHAR"/>
        <association property="author" javaType="com.gupaoedu.domain.Author"
                     column="author_id" select="selectAuthor"/> <!-- selectAuthor 定义在下面-->
    </resultMap>

    <!-- 嵌套查询 -->
    <select id="selectAuthor" parameterType="int" resultType="com.gupaoedu.domain.Author">
        select author_id authorId, author_name authorName
        from author where author_id = #{authorId}
    </select>

其中第二种方式:嵌套查询,由于是分两次查询,当我们查询了Blog 信息之后,会再发送一条SQL到数据库查询部门信息。

我们只执行了一次查询Blog信息的SQL(所谓的1),如果返回了N条记录(比如10条Blog),因为一个Blog就有至少一个Author,就会再发送N条到数据库查询Author信息(所谓的N),这个就是我们所说的N+1的问题。这样会白白地浪费我们的应用和数据库的性能。 如果我们用了嵌套查询的方式,怎么解决这个问题?能不能等到使用Author 信息的时候再去查询?这个就是我们所说的延迟加载,或者叫懒加载。 在MyBatis里面可以通过开启延迟加载的开关来解决这个问题。

延迟加载

在settings标签里面可以配置:

代码语言:javascript
复制
        <!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false  -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖-->
        <setting name="aggressiveLazyLoading" value="true"/>
        <!--  Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认JAVASSIST -->
        <setting name="proxyFactory" value="CGLIB" />

lazyLoadingEnabled决定了是否延迟加载(默认false)。 aggressiveLazyLoading决定了是不是对象的所有方法都会触发查询。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 嵌套结果
  • 嵌套查询
  • 延迟加载
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档