mybatis 级联查询

有时候我们的POJO对象经常不是一个简单的对象,往往存在着一对一或者一对多的关系。就如一个学生可以有一个班主任,有多门课程一样:

public class StudentCourse {
    private String sId;
    private String sName;
    private String sBirth;
    private String sSex;
    private Teacher teacher;
    private List<Course> courseList;
}

这种情况就是级联了。

mybatis 中的三种级联

  • association:代表一对一关系。
  • collection:代表一对多关系。
  • discriminator:鉴别器,允许根据特定的条件去关联不同的结果集

association 一对一级联


假定:学生(Student)和班主任(Teacher)是一对一的关系:

public class Student {
    private String sId;
    private String sName;
    private String sBirth;
    private String sSex;
    private Teacher teacher;
}
<!--查询学生的接口-->
<select id="getStudent" resultMap="oneToOneMap">
    select s_id,s_name,s_birth,s_sex from Student
    where s_id in (01)
</select>

<!--查询老师的接口-->
<select id="selectTeacherById" resultType="om.wys.combineduse.pojo.Teacher">
    select t_name,t_id from Teacher
    where t_id = #{tId}
</select>

<resultMap id="oneToOneMap" type="com.wys.combineduse.pojo.Student">
    <id column="s_id" property="sId" />
    <result column="s_name" property="sName" />
    <result column="s_birth" property="sBirth" />
    <result column="s_sex" property="sSex" />
    <!--在resultMap中调用 查询老师的接口 实现级联查询,column 是 查询老师的接口 的入参-->
    <association property="teacher" column="s_id" select="com.wys.combineduse.dao.StudentMapper.selectTeacherById"/>
</resultMap>

执行的过程:先查询出 Student 的信息,然后根据 column=“s_id” 作为老师 的 tId 查询出老师的信息。


collection 一对多级联

假定:学生(StudentCourse)和课程(Course)是一对多的关系:

public class StudentCourse {
    private String sId;
    private String sName;
    private String sBirth;
    private String sSex;
    private Teacher teacher;
    private List<Course> courseList;
}
<!--查询学生接口-->
<select id="getStudentCourse" resultMap="oneToManyMap">
    select s_id,s_name,s_birth,s_sex from Student
    where s_id in (01)
</select>
<!--查询课程接口 返回值为course-->
<select id="getCourseById" resultType="com.wys.combineduse.pojo.Course">
    select c_id,c_name,t_id from Course
    where t_id = #{tId}
</select>

<resultMap id="oneToManyMap" type="com.wys.combineduse.pojo.StudentCourse">
    <id column="s_id" property="sId" />
    <result column="s_name" property="sName" />
    <result column="s_birth" property="sBirth" />
    <result column="s_sex" property="sSex" />
    <!--一对一的级联查询-->
    <association property="teacher" column="s_id" select="com.wys.combineduse.dao.StudentMapper.selectTeacherById"/>
    <!--一对多的级联查询,自动把Course对象装配进courseList中-->
    <collection property="courseList" column="s_id" select="com.wys.combineduse.dao.StudentMapper.getCourseById"/>
</resultMap>

N+1问题:多一个关联,SQL就要多执行一次。每次取一个Student对象,那么它所有关联的信息都会被取出来。这样会造成SQL执行过多导致性能下降。

注意事项:

需要传递多参数时,在column中用需要用"{}"将参数包起来, =左侧的为mapper中定义的param,也就是实体类中映射的字段, =右侧为主查询的数据库的对应表的表字段名  ,
如:
 <collection property="highList" column="{id= id,standardId= standard_id}" select="getChildById"/>
 单参数传递时不用"{}",如:
 <collection property="highRuleList" column="id" select="getHighRuleList"/>

另一种级联

上面的级联会有N+1的问题,下面这种方式更加的简单和直接:

<!--   主推这种查询,没有n+1问题!-->
<select id="getStudentCourseByOther" resultMap="oneToManyOtherMap">
    select s.s_id,s.s_name,s.s_birth,s.s_sex,t.t_name,t.t_id,c.c_id,c.c_name,c.t_id from Student s
    left join Teacher t on s.s_id = t.t_id
    left join Course c on t.t_id = c.t_id
    where s_id in (01)
</select>

<resultMap id="oneToManyOtherMap" type="com.wys.combineduse.pojo.StudentCourse">
    <id column="s_id" property="sId" />
    <result column="s_name" property="sName" />
    <result column="s_birth" property="sBirth" />
    <result column="s_sex" property="sSex" />
    <association property="teacher" column="s_id" javaType="com.wys.combineduse.pojo.Teacher">
        <id column="t_id" property="tId" />
        <result column="t_name" property="name" />
    </association>
    <!--ofType属性定义的是collection里面的泛型是上面Java类型,MyBatis会拿定义的Java类和结果集做映射-->
    <collection property="courseList" column="s_id" ofType="com.wys.combineduse.pojo.Course" >
        <id column="c_id" property="cId" />
        <result column="c_name" property="cName" />
        <result column="t_id" property="tId" />
    </collection>
</resultMap>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值