【学习笔记】多对一和一对多

多对一和一对多

概念:

以老师和学生为例

多对一:多个学生对应一个老师,关键词【关联】 多个学生关联一个老师

一对多:一个老师对应多个学生,关键词【集合】

 

设计环境

创建老师表和学生表,学生表中有老师表的id作为外键

image-20230105151326276

在java模型中 teacher 还是和之前一样两个属性(id,name)都不是对象,而student中的tid是Teacher对象

public class Student {
    private int id;
    private String name;
​
    private Teacher teacher;
}

 

 

多对一需求

查询所有学生和其对应的老师

之前可以通过sql去实现,子查询和联表查询

子查询:

select s.id,s.name,t.name from student s, teacher t where s.tid=(
   select id from teacher where tid = 1
)

联表查询:

select s.id,s.name,t.name from student s,teacher t where s.tid = t.id

 

现在我们在mybatis中,通过xml 标签去实现,就不像之前那么简单,因为student 的数据库的列tid与Student实体类的Teacher类不对应,所以要使用结果集映射 resultMap

resultMap 中的 result标签不能用于对象和数据库列的映射,所以我们要使用 association

有两种方式:

  • 按照查询 嵌套处理

    这种方式就像子查询,先在student表中查出所有的信息,使用结果集映射resultMap

    用association 标签 将 Teacher类与数据库中的列tid映射,并且在嵌套一层查询(就是从association 标签中 再写一个 select属性 这个 select属性 绑定 查询teacher表的 select标签)

    在查询teacher标签的中通过tid去查

    <select id="getStudent1" resultMap="StudentTeacher">
        select * from jdbcstudy.student
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" resultType="Teacher">
        select * from jdbcstudy.teacher where id = #{tid}
    </select>

 

  • 按照结果 嵌套处理

    这种方式就像联表查询,在student的select标签中写入完整的联表查询sql语句,并且给每个字段取一个别名,然后绑定一个resultMap,其中的result标签是将sql中的别名与student实体类的属性绑定,resultMap中的association标签 的属性只写 teacher对象的名称和javaType(Teacher实体类)标签的内容是将Teacher的属性与sql的别名绑定

    <select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid,s.name sname,t.id tid,t.name tname from student s,teacher t where s.tid = t.id
    </select>
    ​
    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <result column="tname" property="name"/>
            <result column="tid" property="id"/>
        </association>
    </resultMap>

 

一对多

一对多是集合

查询某个老师的以及该老师对应的学生

与多对一大体相同,不同的是实体类中,学生类的属性不是对象,老师类有学生类的集合

public class Student {
    private int id;
    private String name;
    private int tid;
}
public class Teacher {
    private int id;
    private String name;
    
    private List<Student> students;
}

 

还是有两种方式

  • 按照结果嵌套处理

    <select id="getTeacher1" resultMap="TeacherStudent">
        select t.id tid,t.name tname,s.id sid,s.name sname, s.tid stid from teacher t,student s where t.id = #{id}
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="stid"/>
        </collection>
    </resultMap>

    与之前不同的地方:

    • 因为是一对多,所以用的标签是collection

    • collection的属性从javaType变成 ofType

      • javaType是实体类中属性的类型

      • ofType是实体类中集合的泛型类型

 

  • 按照查询嵌套处理

    <select id="getTeacher2" resultMap="TeacherStudent2">
        select * from teacher where id = #{id}
    </select>
    <resultMap id="TeacherStudent2" type="Teacher">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudent"/>
    </resultMap>
    <select id="getStudent" resultType="Student">
        select * from student where tid = #{id}
    </select>

    与之前不同的地方:

    • 同样标签使用的是collection

posted @ 2023-01-05 18:12  GrowthRoad  阅读(112)  评论(0编辑  收藏  举报