Mybatis的关联映射(1-1,1-n,n-n)

人走茶凉 提交于 2020-02-04 11:31:55

Mybatis的关联映射(1-1,1-n,n-n)

  1. 一对一
  2. 一对多
  3. 多对多
  4. 一张表的一对多(自查询)

一对一

表:address 与 students
在这里插入图片描述
在这里插入图片描述
1.嵌套结果:
一条sql语句,在select后b把两张表中要查询出来的所有的列名写出来,一个列名对应一个属性值(两个对象中的属性),最后一一映射起来。association标签有两个属性、有子标签(从以下代码中可以看出,select 后的所有列,在resultMap中都有对应的column与之匹配。注意1.column与select后的列名的名称一定要各自对应,并且property的属性值a一定要在对应的类中有对应的setA()方法。)

<!--Address的所有属性的映射-->
    <resultMap id="AddressResultMap" type="com.briup.review.OneToOne.Address">
        <id column="addr_id" property="addrId"></id>
        <result column="city" property="city"></result>
    </resultMap>
<!--Students的基本属性的映射(不包括对象属性)-->
    <resultMap id="StudentBaseResultMap" type="com.briup.review.OneToOne.Students">
        <id column="stud_id" property="studId"></id>
        <result column="username" property="username"></result>
        <result column="addr_id" property="addrId"></result>
    </resultMap>
<!--嵌套结果-->
    <resultMap id="StudenetResultMap" type="com.briup.review.OneToOne.Students" extends="StudentBaseResultMap">
        <!--基本属性通过extends获得-->
        <association property="address" javaType="com.briup.review.OneToOne.Address">
            <id property="addrId" column="addr_id"></id>
            <result property="city" column="city"></result>
        </association>
    </resultMap>
 <!--如果result中不写某一列的映射,那么这一列默认为它自己的数据类型的默认值-->
    <select id="selectStudents" resultMap="StudenetResultMap">
        select s.stud_id,s.username,s.addr_id,a.addr_id,a.city
        from students s , address a
        where s.addr_id=a.addr_id
    </select>    

2.嵌套查询
2条sql语句,association中没有自己的子标签,属性值有4个。(这两种方法中association的property的值都是对象属性,不是基本数据类型的)。原理通过select语句查询到的外键的int类型的值映射到column一列,在通过select属性对性的select语句把查询到的结果映射到property对应的属性值上。(以下代码中,由于students的addr_id列在基本属性的resultMap和association中都有,故,它映射了两次,一次addrId,一次address,由此可见,column=addr_id出现几次就映射几次,知识每次都是根据不同的映射规则映射,如果映射失败就默认为int或null.).

<!--嵌套查询-->
    <resultMap id="StudenetResultMap"  type="com.briup.review.OneToOne.Students" extends="StudentBaseResultMap">
        <!--基本属性通过继承获得-->
        <!--其他属性通过嵌套查询获得-->
        <association property="address" column="addr_Id"
                     javaType="com.briup.review.OneToOne.Address"
                     select="selectAddressById"></association>
    </resultMap>
    <select id="selectAddressById" parameterType="java.lang.Integer" resultMap="AddressResultMap">
        select * from address where addr_id=#{id}
    </select>
    <select id="selectStudents" resultMap="StudenetResultMap2">
        select *
        from students s 
    </select>

在这里插入图片描述

一对多

表:students 、classroom
1.嵌套查询
一个教室对应多个学生,在学生表中加入教室标的主键作为外键。在Classroom类中添加List students属性。这种映射有2条sql语句,collection中有4个属性,没有子标签。与一对一的区别,由association编程了collection,由javaType编程了ofType,映射原理:根据查询出来的。(以下代码查出来的classroom中包含了List,而每一个students 中又包含了一个Address)

<!--Classroom的基本属性的映射-->
	<resultMap id="ClassroomBaseResult" type="com.briup.review.OneToOne.Classroom">
        <id property="cId" column="c_id"></id>
        <result property="name" column="c_name"></result>
    </resultMap>
    <resultMap id="ClassroomResult" type="com.briup.review.OneToOne.Classroom" extends="ClassroomBaseResult">
        <!--基本属性通过extends获得-->
        <!--students属性通过classroom的主键c_id来查询获得-->
        <collection property="students" column="c_id" ofType="com.briup.review.OneToOne.Students"
               select="selectStudentsByCId" ></collection>
    </resultMap>
    <select id="selectStudentsByCId"  parameterType="java.lang.Integer" resultMap="StudenetResultMap">
        select *
        from students
        where students.c_id =#{id}
    </select>
    <select id="selectClassroom" resultMap="ClassroomResult">
        select *
        from classroom
    </select>

2.嵌套结果
1条sql语句,collection标签中有两个属性,有子标签。(select后边的每一个列都与resultMap的子标签的id或result的column对应。)

<!--嵌套结果-->
    <resultMap id="ClassroomResult2" type="com.briup.review.OneToOne.Classroom" extends="ClassroomBaseResult">
        <!--基本属性通过extends获得-->
        <!--students属性通过嵌套结果来获得-->
        <collection property="students" ofType="com.briup.review.OneToOne.Students">
            <!--这部分写需要映射的students的属性及键-->
            <id property="studId" column="stud_id"></id>
            <result property="username" column="username"></result>
            <result property="addrId" column="addr_id"></result>
            <!--不能再映射address了,result没有select属性,而且没有子标签,但是嵌套查询却可以-->
        </collection>
    </resultMap>
    <select id="selectClassroom" resultMap="ClassroomResult2">
        select c.c_id,c.c_name,s.stud_id,s.username,s.addr_id
        from classroom c left join students s
        on c.c_id=s.c_id;
    </select>

在这里插入图片描述

多对多

表:students teacher t_s
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
1.嵌套查询
创建中间表,在Teacher类中添加List(以下代码块中最后能查到Teacher中的student,且student中的address也能查到)

<!--基本属性映射-->
    <resultMap id="TeacherBaseResult" type="com.briup.review.OneToOne.Teacher">
        <id property="tId" column="t_id"></id>
        <result property="name" column="name"></result>
    </resultMap>
    <resultMap id="TeacherResult" type="com.briup.review.OneToOne.Teacher" extends="TeacherBaseResult">
        <!--基本属性通过extends获得-->
        <!--students属性通过根据t_id查询得到List<Students>获得-->
        <collection property="students" column="t_id"
                    ofType="com.briup.review.OneToOne.Students"
                    select="selectStudentByTId"></collection>
    </resultMap>
    <!--嵌套查询-->
    <select id="selectStudentByTId" parameterType="java.lang.Integer" resultMap="StudenetResultMap">
        select s.*
        from students s,t_s
        where s.stud_id in (
            select t_s.s_id from t_s where t_s.s_id=s.stud_id
            and t_s.t_id=#{id}
        )
    </select>
    <select id="selectTeacher" resultMap="TeacherResult">
        select teacher.t_id,teacher.name
        from teacher
    </select>

2.嵌套结果

	<resultMap id="TeacherResultMap" type="com.briup.review.OneToOne.Teacher" extends="TeacherBaseResult">
        <!--基本属性通过extends获得-->
        <!--students属性通过根据t_id查询得到List<Students>获得-->
        <collection property="students" column="t_id" select="selectStudentByTId">
            <result property="username" column="username"></result>
        </collection>
    </resultMap>
    <!--嵌套结果-->
    <select id="selectTeacher" resultMap="TeacherResultMap">
        select t.t_id,t.name,s.username
        from teacher t,students s,t_s ts
        where ts.t_id = t.t_id
        and ts.s_id = s.stud_id
    </select>

在这里插入图片描述

一张表的一对多

表:category
描述:在一级标题下又有二级标题。在Category类中添加属性List category,表示当这个标题是一级标题的时候,c是这个一级标题的所有二级标题,当这个标题是二级标题的时候,category为null。
在这里插入图片描述
1.嵌套结果

	<resultMap id="CategoryResultMap" type="com.briup.review.OneToOne.Category">
        <id property="id" column="id"></id>
        <result property="title" column="title"></result>
        <result property="parent_id" column="parent_id"></result>
        <collection property="category" ofType="com.briup.review.OneToOne.Category">
            <id property="id" column="id2"></id>
            <result property="title" column="title2"></result>
        </collection>
    </resultMap>
    <select id="selectCategory" resultMap="CategoryResultMap">
        select c1.id,c1.title,c1.parent_id,c2.id id2,c2.title title2
        from category c1 left join category c2
        on c1.id = c2.parent_id
    </select>

2.嵌套查询

	<resultMap id="CategoryBase" type="com.briup.review.OneToOne.Category">
        <id property="id" column="id"></id>
        <result property="title" column="title"></result>
        <result property="parent_id" column="parent_id"></result>
    </resultMap>
    <resultMap id="CategoryResultMap2" type="com.briup.review.OneToOne.Category" extends="CategoryBase">
        <collection property="category" ofType="com.briup.review.OneToOne.Category"
                column="id" select="selectCategoryByPId"  ></collection>
    </resultMap>
    <select id="selectCategoryByPId" resultMap="CategoryBase">
        select c.id,c.title,c.parent_id
        from category c
        where parent_id=#{id}
    </select>

    <select id="selectCategory" resultMap="CategoryResultMap2">
        select c.id,c.title,c.parent_id
        from category c
    </select>

在这里插入图片描述

总结

1.嵌套结果,association或collection中有四个属性,没有子标签
嵌套查询,有两个属性,有子标签。
2.可以在一个resultMap中同时存在collection和association两个子标签。
3.一对多嵌套查询可以查出“一”的一方对应一对一关系的“一”的另一方,但是嵌套结果不行。
4.嵌套结果比嵌套查询简单,且更灵活,想要什么属性,在select之后写上就好,除非是对象属性,就不能了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!