首页 > 其他分享 >MyBatis用嵌套ResultMap实现一对多映射

MyBatis用嵌套ResultMap实现一对多映射

时间:2024-07-12 19:10:05浏览次数:9  
标签:name course 张三 tutor ResultMap 嵌套 李四 MyBatis id

背景

我们知道,MyBatis可以很方便地把SQL select出来的数据直接映射为对象的属性,把对象取出来。

但是,有些对象的属性是集合类型,集合里保存的是数个其他类型的对象。如何用MyBatis把它取出来呢?

例子

以以下这个应用场景为例:一个教师对应多个课程。

数据结构如下:

复制代码
public class Course{
    int id;
    String name;    
}

public class Tutor{
    int id;
    String name;
    List<Course> courses;
}
复制代码

这时,就需要分别写出两者的ResultMap:

复制代码
    <resultMap type="Course" id="courseResult">
        <result column="course_id" property="id" />
        <result column="course_name" property="name" />
    </resultMap>

    <resultMap type="Tutor" id="tutorResult">
        <id column="tutor_id" property="id" />
        <result column="tutor_name" property="name" />
        <collection property="courses" resultMap="Course" />
    </resultMap>
复制代码

然后把select语句的resultMap设为tutorResult:

<select id="findTutorById" parameterType="int" resultMap="TutorResult"> 
    SELECT TUTOR_ID, TUTOR_NAME, COURSE_ID, COURSE_NAME FROM TUTOR
</select>

这样就能把Tutor类的数据正确地读进来了。

实验

以上这个例子来自《Java Persistence with MyBatis3》。让我好奇的是,myBatis是如何判断,哪些course应该对应同一个tutor的呢?对于每个course,它是怎么寻找应该把它放进哪个tutor的List里呢?

用以上的例子,数据为:

tutor_id tutor_name course_id course_name
1 张三 1 语文
2 李四 2 数学

读进来的数据是,大概是这样的:

张三 : 语文
李四 : 数学

如果我们把数据改成这样:

 

tutor_id tutor_name course_id course_name
1 张三 1 语文
1 李四 2 数学

读进来的数据,就会变成这样:

张三:语文, 数学

“李四”没有了。数学归进了张三里。这是为什么呢?

原来,Tutor的ResultMap里,指定了id为tutor_id。一旦指定了id,myBatis就认定它是全局唯一的;李四的id与张三相同,因此会被认为是同一个对象,则李四的数据被直接忽略。

上面这个例子可以说明,如果有指定id,会去根据id判断是否为同一个对象。id相同,即使属性不同,还是认为是同一个对象。

而我们如果把id改为普通的result,把Tutor的ResultMap改成这样:

    <resultMap type="Tutor" id="tutorResult">
        <result column="tutor_id" property="id" />
        <result column="tutor_name" property="name" />
        <collection property="courses" resultMap="Course" />
    </resultMap>

此时,仍然用刚才的数据:

tutor_id tutor_name course_id course_name
1 张三 1 语文
1 李四 2 数学

则读进来的数据,就会变成这样了:

张三:语文
李四:数学

上面这个例子可以说明,如果没有指定id,会去根据所有属性去判断是否为同一个对象。只要有一个属性不同,就认为不是同一个对象。

如果把数据改为:

tutor_id tutor_name course_id course_name
1 张三 1 语文
1 张三 2 数学

则读进来的数据,就会变成:

张三:语文,数学

如果所有属性都相同,就会认为是同一个对象了。

写到这里,发现思路不太清晰。其实course按照什么去找tutor,主要看的是同一行的tutor,看是这个tutor是不是新的。

标签:name,course,张三,tutor,ResultMap,嵌套,李四,MyBatis,id
From: https://www.cnblogs.com/joe-tang/p/7144963.html

相关文章

  • Mybatis模糊查询MySQL中记录的的常用三种方法
    mybatis的模糊查询功能使用的很广泛,以MySQL数据库为例(不同的数据库,有些可能不支持) 常用的模糊查询有三种方法:直接使用%拼接字符串,如 '%'#{name}'%' 或 "%"#{name}"%",单引号或双引号都可以。(或者  '%${vendorId}%' )<iftest="vendorId!=nullandvendorId!=......
  • Mybatis association与collection的区别
    mybatisassociation与collection的区别:一、一对一 association通常用来映射一对一的关系1<resultMaptype="cn.itcast.mybatis.po.Orders"id="OrdersUserResultMap">23<!--配置映射的订单信息-->4<idcolumn="id"prope......
  • mybatis动态Sql(where)和sql片段
    sql片段的定义;1<sqlid="condition">2<iftest="entity.dicttype!=null">and`dicttype`=#{entity.dicttype}</if>3<iftest="entity.dictname!=nullandentity.dictname!=''......
  • 【Springboot】玩转复杂单元测试启动类-只测试数据访问层(JPA+Mybatis) 和服务层 以及
    上一篇文章写了一个最复杂的SpringBootTest启动类,定制化程序奇高,然而有时候仅测试JPA是不够的。启动类需求:测试SpringDataJPA测试Mybatis从容器中获得ObjectMapper测试单独的Service使用TestNG或者使用Junit阻止Dubbo、Kafka、ElasticSearch等中间件启动使用appl......
  • 易优cms网站notempty功能:判断某个变量是否为空,可以嵌套到任何标签里面使用-Eyoucms
    【基础用法】名称:notempty功能:判断某个变量是否为空,可以嵌套到任何标签里面使用,比如:channel、type等语法:{eyou:notemptyname='$eyou.field.seo_title'/}{$eyou.field.seo_title}{/eyou:notempty}文件:无参数:name=''变量名底层字段:无 【更多示例】-------------------------......
  • Mybatis-Plus最优化持久层开发
    Mybatis-plus:最优化持久层开发一:Mybatis-plus快速入门:1.1:简介:Mybatis-plus(简称MP)是一个Mybatis的增强工具,在mybatis的基础上只做增强不做改变;提高效率;自动生成单表的CRUD功能;提供了丰富的条件拼接方式;全自动ORM类型持久层框架;(不仅提供数据库操作的方法,还会提供sql语句......
  • mybatis中的标签
    在MyBatis中,除了基本的SQL映射功能外,还有许多用于动态SQL构建的标签。这些标签允许我们根据不同的条件和需求构建复杂的SQL语句。主要的动态SQL标签包括<if>,<choose>,<when>,<otherwise>,<trim>,<set>,<foreach>,以及<bind>等。下面详细介绍这些标签的用途和用法。......
  • MyBatis Generator代码生成器
    1、MyBatisGenerator代码生成1、概述MyBatisGenerator作为一个基于MyBatis的独立工具,它可以通过简单的配置去帮我们生成数据表所对应的PO、DAO、XML等文件,减去我们手动去生成这些文件的时间,有效提高开发效率2、环境集成使用idea打开项目:mybatis-gen然后修改代码生......
  • 流式查询1. mybatis的游标Cursor,分页大数据查询
    流式查询流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用可以通过迭代器每次取一条查询结果。流式查询的好处是能够降低内存使用。例如我们想要从数据库取1000万条记录而又没有足够的内存时,就不得不分页查询。而分页查询就需要我们按照顺序查询并设置一个参......
  • MyBatis拦截器在实际项目中的应用
    MyBatis 是一个流行的Java持久层框架,它简化了数据库访问的复杂性,为开发者提供了强大的功能。其中,MyBatis拦截器是一个非常有用的特性,可以帮助开发者灵活地解决各种问题。一、MyBatis拦截器1.1从执行SQL语句的核心流程说起在MyBatis中,要执行一条SQL语句,会涉及......