Mybatis09-多对一

背景

要解决的问题:
实体类中老师是学生的属性,是一个对象,但是数据库中对应的学生表格中老师的属性为tid是一个int型,
将数据库中老师信息于学生表格中老师的信息对应起来.(多个学生一个老师)

在这里插入图片描述

按照查询嵌套处理

先查询所有学生,然后根据学生的tid查询对应的老师, 子查询。
接口中的方法不用改变,要改变的是 StudentMapper.xml 中怎么用 SQL

<!--    思路:       
 1.查询所有的学生信息        
 2.根据查询出来的学生的tid,寻找对应的老师!  
 子查询    -->
<select id="getStudent" resultMap="StudentTeacher">    
    select * from student
</select>
<resultMap id="StudentTeacher" type="Student">   
 <!--属性和字段本身就能对应起来的,可以不写-->
    <result property="id" column="id"/>    
    <result property="name" column="name"/>    
    <!--复杂的属性,我们需要单独处理 
    对象: association 集合: collection-->  
    		<!-- property 对象属性 colum 数据库列名-->  
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
 <!--根据 id 查询老师 只有一个参数可以不写-->
<select id="getTeacher" resultType="Teacher">    
    select * from teacher where id = #{id}
</select>

association 可以指定关联的 JavaBean 对象, property 代表关联对象的属性,column 为对应的数据库中相应表的字段.
本题中数据库字段 tid 与 teacher 也不一致,所以要指定一个查询,通过 tid 查询到 teacher 对象。
在这里插入图片描述

这种方法本质上其实是嵌套了一个子查询,即先查学生再查对应的老师,对 Student 执行一次查询,在 Student 里再对 Teacher 执行一次查询。

按照结果嵌套处理

先用 SQL 语句将需要的属性、对象统一查询出来,再通过 resultMap 中 association 使查询出来的字段与属性对应.
在接口中再创建一个方法

public interface StudentMapper {
    ...
	 // 获取所有学生及其对应的老师信息,按照结果嵌套处理
    public List<Student> getStudent2();
}

再写这个方法使用的 SQL 语句和结果集映射

<!--按照结果嵌套处理-->
<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="sname"/>    
    <association property="teacher" javaType="Teacher">        
        <result property="name" column="tname"/>    
    </association>
</resultMap>

测试方法中直接把 mapper 调用的方法改成 getStudent2 就行了,直接看结果

运行效果如下:
在这里插入图片描述
老师的 id 都是0,原因很显然,这种方法是先查属性再做对应,这里一没查老师的 id 二没做对应,所以老师的 id 肯定显示不出来。

将老师的id也加进来

 <!--按照结果嵌套处理-->
    <!--查询的结果 本质上还是个 Student-->
    <resultMap id="StudentTeacher2" type="Student">
        <!--属性和字段本身就能对应起来的,可以不写-->
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <!--对应,要查找的属性叫 teacher 它是 Teacher 类型的-->
        <association property="teacher" javaType="Teacher">
            <!--将查找出来的 tname 与 老师中的属性 name 对应-->
            <!-- ++++++加入 老师id 的对应--> 
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
        </association>
    </resultMap>

    <select id="getStudent2" resultMap="StudentTeacher2">
        <!-- ++++++多查一个 t.id 出来--> 
        select s.id as sid, s.name as sname, t.id as tid, t.name as tname
        from student s, teacher t
        where s.tid = t.id
    </select>

总结

总的来说,多对一的查询,有两种方法

按照查询嵌套处理:本质上是子查询,用当前查出来的信息再做一次查询
按照结果嵌套处理:本质上是联表查询,直接查出来所有信息再给它们对应上
我感觉第二种更好用,即没改变 SQL 本身,也不用写多个查询标签。

注意:如果在 IDEA 中设置了 SQL Dialects,则 SQL 语句中的表名前要加上数据库库名,否则会报红,不过其实不影响执行(猜测是 IDEA 无法识别到这张表,但执行的时候数据源中指定了数据库,所以能查到正确的表)。但去掉设置后 IDEA 无法给出输入提示了,如表名要纯手打。为了干净一点我后面还是去掉了。

提醒:在 IDEA 中使用数据库 Console,一定要对着要使用的数据库打开 Console,否则会识别不了表(在表前加上数据库名也行,不过多丑啊)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值