MyBatis一对多、多对一映射

文章详细讲解了如何在Java应用中使用ORM框架处理数据库查询,涉及一对一和多对多关系的嵌套查询以及如何通过resultMap进行结果映射,包括使用`<association>`和`<collection>`标签的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表格:

Student

字段类型备注
idint主键
namevarchar2姓名
tidint教师id

Teacher

字段类型备注
idint主键
namevarchar姓名

多对一(或者一对一):association

Student类

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

Teacher类

public class Teacher {
    private int id;
    private String name;
}

第一种,按照结果嵌套查询

这种就简单的理解为 :

我们已经把需要的表并在一起了,我们只需要选择我们需要的属性进行映射就行了。

<select id="getStudent2" resultMap="StudentTeacher2">
    select  s.id sid,s.name sname, 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="name"/>
    <association property="teacher" javaType="teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>
<!--
<association property="teacher" javaType="teacher">
        <result property="name" column="tname"/>
</association>
这种比较简单,<association>用来映射Student类的teacher属性 这个属性的类型也就是 javaType="teacher";

<select id="getStudent2">中我们需要的是 teacher的name属性,那么我们只需要映射一下tname就行
<result property="name" column="tname"/>

-->    

第二种:按查询进行嵌套处理

这中就简单的理解为子查询

我们先查学生表的所有信息,将查到的tid 给子查询,让子查询找到对应的数据,再把结果返回

<select id="getStudent" resultMap="StudentTeacher">
    select * from student
<!-- select id,name,tid from student -->    
</select>

<resultMap id="StudentTeacher" type="student">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <association property="teacher" javaType="teacher" select="getTeacher"column="tid"/>
</resultMap>
<!--
<association property="teacher" javaType="teacher" select="getTeacher"column="tid"/>
我们可以这样理解这句话:
我需要映射Student类的teacher属性,这个属性的java类型是Teacher,这个属性的数据从哪里来呢,我们需要调用 getTeacher 这个sql语句去查询,同时要传递给这个sql语句 参数进行查询。这个参数就是我们从 getStudent 查询语句中查出来的 tid 
-->

<select id="getTeacher" resultType="teacher">
    select * from teacher where id = #{??};
</select>
<!--
我们发现 id = #{??} #{}里面的内容即使改变了,对查询语句的结果是没有任何影响的
我们可以将理解为这样  select * from teacher where id = ?; 
我们知道sql中有预编译,也许本质就是下面这样呢 
preparedStatement.setInt(1, resuleSet.getInt("tid"));
当然,具体流程是啥我不清楚。只是想让大家明白 #{??} 里面的内用没啥影响,但不能为空,大家可以自己试一下。
-->

一对多:collections

Student类

public class Student2 {
    private int id;
    private String name;
    private int tid;//关联老师
}

Teacher类

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

第一种,按照结果嵌套查询

<select id="getTeacher" resultMap="TeacherStudent">
    select s.id sid, s.name sname, t.name tname, t.id tid
    from student s,teacher t
    where s.tid = t.id and t.id = #{tid}
</select>

<resultMap id="TeacherStudent" type="Teacher2">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>

    <collection property="students" javaType="ArrayList" ofType="Student2">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>
<!--
只要理解了上面的association,这个也就很好理解了
我们使用<collection> 去映射teacher类的students属性。
students 的 java类型是个集合 , 集合里面存放的数据类型也就是泛型,是 ofType="Student2"
-->    

第二种:按照查询进行嵌套

<select id="getTeacherById" resultMap="TeacherStudent">
	select id ddd, name from teacher where id = #{tid}
</select>

<resultMap id="TeacherStudent" type="Teacher2">
	<result property="id" column="ddd"/>
	<result property="name" column="name"/>
	<collection property="students" javaType="ArrayList" ofType="Student2"
            select="getStudentByTid" column="ddd"/>
</resultMap>

<select id="getStudentByTid" resultType="student2">
	select * from student where tid = #{hh}
</select>
<!--
同样, getStudentByTid 中的参数仍旧跟 #{}中的内容没有关系
而且,切记 ! column一定是跟我们从数据库中查出来的列名保持一致
-->

有错误请指正,共同学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值