Mybatis级联:关联、集合和鉴别器的使用

Mybatis中级联有关联(association)、集合(collection)、鉴别器(discriminator)三种。其中,association对应一对一关系、collection对应一对多关系、discriminator可以根据情况选择采用哪个类作为实例,关联不同的结果集。

一、关联

Mybatis的关联有两种方式:

  • 嵌套查询:通过执行另外一个 sql映射语句来返回预期的复杂类型
  • 嵌套结果:使用嵌套结果映射来处理重复了联合结果的子集

场景一:一个部门Department有一个部门经理Leader

<!--    嵌套查询 (N+1查询问题)    -->
<resultMap type="Department" id="deptResult">
  <id property="id" column="d_id"/>
  <result property="name" column="d_name"/>
  <association property="leader" column="leader_id" select="getLeader" javaType="Leader"/>
</resultMap>
<select id="getDept" parameterType="int" resultMap="deptResult">
  select * from department where d_id=#{id}
</select>

<select id="getLeader" parameterType="int" resultType="Leader">
  select * from leader where l_id=#{id}
</select>

<!--    嵌套结果    -->
<resultMap type="task.Department" id="deptResult">
  <id property="id" column="d_id"/>
  <result property="name" column="d_name"/>
  <association property="leader" javaType="Leader">
    <id property="id" column="l_id"/>
    <result property="name" column="l_name"/>
  </association>
</resultMap>
<select id="getDept" parameterType="int" resultMap="deptResult">
  select * from department d, leader l where d.leader_id = l.l_id and d.d_id=#{id}
</select>

场景二:获取指定部门的所有上级部门(获取子结点的所有父结点,一个结点最多只有一个直接父结点)

<resultMap type="Department" id="deptResult">
  <id column='id' property='id'/>
  <result column='name' property='name'/>
  <association property='parent' javaType='Department' select='getPDept' column='p_id'/>
</resultMap>
<select id="getDept" resultMap="deptResult">
  select id,name,p_id from department where id =#{id}
</select>

二、集合

和关联一样,集合也有嵌套查询和嵌套结果两种方式,只是多了个关键字ofType,用来区分JavaBean属性类型和集合包含的类型。

场景:一个部门Department有多个员工Worker

<!--    嵌套查询    -->
<resultMap type="Department" id="deptResult">
    <id property="id" column="id"/>
    <result  property="name" column="d_name"/>
    <!--    javaType属性不是必需的    -->
    <collection property="workers" javaType="ArrayList" column="id" ofType="Worker" select="getWorkers"/>
</resultMap>
<resultMap type="Worker" id="workerResult" >
    <id property="id" column="w_id"/>
    <result  property="name" column="w_name"/>
    <result property="age" column="age"/>
</resultMap>
<select id="getDept" parameterType="int" resultMap="deptResult">
    select id,d_name from department where id=#{id}
</select>
<select id="getWorkers" parameterType="int" resultMap="workerResult">
    select w_id,w_name,age from worker where d_id=#{id}
</select>

<!--    嵌套结果    -->
<resultMap type="Department" id="deptResult">
    <id property="id" column="id"/>
    <result  property="name" column="d_name"/>
    <collection property="workers"  ofType="Worker">
        <id property="id" column="w_id"/>
        <result property="name" column="w_name"/>
        <result property="age" column="age"/>
    </collection>
</resultMap>
<select id="getDept" parameterType="int" resultMap="deptResult">
    select id,d_name,w_id,w_name,age from department,worker where id=d_id and id=#{id}
</select>

三、鉴别器

有时一个数据库查询语句会返回很多不同数据类型的结果集。鉴别器用于处理这种情况,还包括类的继承层次结构,其表现相当于Java中的switch语句。

场景:交通工具Vehicle,有子类小汽车Car,卡车Truck两种类型,根据vehicle表中type字段区别数据,将查询出的数据自动封装成不同类型的对象

<resultMap type="Vehicle" id="vehicleResult">
    <id property="id" column="id"/>
    <result property="color" column="color"/>
    <discriminator javaType="int" column="type">
        <case value="1" resultType="Car">
            <result property="doorCount" column="door_count"></result>
        </case>
        <case value="2" resultType="Truck">
            <result property="boxSize1" column="box_size1"></result>
            <result property="boxSize2" column="box_size2"></result>
        </case>
    </discriminator>
</resultMap>
<select id="getVehicle" resultMap="vehicleResult">
    select * from vehicle
</select>
原文地址:https://www.cnblogs.com/aaron-shu/p/7812755.html