Mybatis学习-复杂查询

写在前面

设想一下这个场景:
一个老师名下有许多学生,而每个学生只能由一个老师教(班主任),那么在学生表中关联老师这个对象,在老师对象中,会有一个学生的集合。那么这种情况下,Mybatis进行SQL查询时,就不会像简单查询一样简单了。
这就涉及到一对多,多对一的问题。
问题场景中的学生类、老师类分别为(省略了getter,setter等方法):
Student类

public class Student {
    private int id;
    private String name;

    //学生需要关联一个老师
    private Teacher teacher;
    private int tid;//关联的老师id
 }

Teacher类

public class Teacher {
    private int id;  //老师id
    private String name; //老师姓名

    private List<Student> students; //老师对应一群学生
 }

Student的相关接口

public interface StudentMapper {
     List<Student> getStudentInfo(); //方法一
     List<Student> getStudentInfo2(); //方法二
}

Teacher的相关接口

public interface TeacherMapper {
    //根据Id查询老师
    @Select("select * from teacher where id = #{tid}")
    Teacher getTeacherById(@Param("tid") int id);
    Teacher getTeacherById2(@Param("tid") int id);
    //查询所有老师
    List<Teacher> getTeachers();
}

多对一

多对一,就是以学生类(多数)为主题,他关联着“老师”这个对象,在处理查询学生信息,顺带要查询其关联的老师的信息时,可以通过如下方法:
方法一:子查询
在StudentMapper.xml配置文件中写下如下SQL语句:

<!--联表查询方式一:子查询-->
    <select id="getStudentInfo" resultMap="StudentTeacher">
        select * from student
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂的属性,我们需要单独处理,对象:association,集合:collection-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacherById"/>
    </resultMap>
    <select id="getTeacherById" resultType="Teacher">
        select * from teacher where id = #{tid}
    </select>

这种方法是利用子查询。
因为学生对象关联着老师对象,所以查询学生对象时,要在父查询中嵌套一个子查询,用来查询对应的老师信息。

方法二:按照结果嵌套处理(推荐)

<!--联表查询方式二:按照结果嵌套处理-->
    <select id="getStudentInfo2" resultMap="StudentTeacher2">
        select  s.id sid,s.name sname,t.name tname,t.id tid
        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"/>
            <result property="id" column="tid"/>
        </association>
    </resultMap>

此时,就需要在SQL语句上下功夫,将查询到的数据起别名,做ResultMap映射

一对多

一对多就是一个老师对象管理着多个学生(一个学生队列),查询某个老师时,还要把他所管理的学生队列中的信息查询出来
方法一:联表查询(推荐)
在TeacherMapper.xml配置文件中写如下SQL标签(注意:针对哪个主体做查询,就在哪个主体下的配置文件中写SQL标签)

<!--按结果嵌套查询-->
    <select id="getTeacherById" 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="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!--
            接下来是对集合的处理
            ofType属性代表集合中的java类型
        -->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

方法二:子查询

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

子查询可以不在Mapper(Dao)层的接口中写出,而仅仅只需要在xml配置文件中写出,而子查询的参数,由resultMap中的collection标签的column给出.

【注】:

  1. JavaType是实体类中的属性的类型
  2. ofType是集合中泛型的类型
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值