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


    我的技术博客经常被流氓网站恶意爬取转载。请移步原文:http://www.cnblogs.com/hamhog/p/3959451.html,享受整齐的排版、有效的链接、正确的代码缩进、更好的阅读体验。

    背景

    我们知道,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是不是新的。

  • 相关阅读:
    2:(sql语言的数据类型)
    4:关系数据库标准语言sql(sql概述:功能,特点)
    毕业设计:反射,枚举
    毕业设计:阶段性总结
    3.9易错题
    3.8(关系代数表达查询)
    3.7(附加的关系运算)
    3.5(关系的完整性约束)、(关系代数的五种基本运算:选择和投影(关于行运算和列运算的概念还不清晰))
    3.4(从E-r概念模型到关系模型即DBMS直接支持的数据模型)
    php 如何获取图片后缀和可变函数的使用实战
  • 原文地址:https://www.cnblogs.com/hamhog/p/3959451.html
Copyright © 2020-2023  润新知