mybatis的resultMap屬性----association和collection

一、association

1、級聯查詢的時候,可以在一個 java bean裏定義一個要關係 的類類型。在resultMap中寫bean.屬性名從而關聯別一個表的字段, eg;

@Alias("emp")
public class Employee {

    private Integer id;
    private String lastName;
    private String email;
    private String gender;
    private Department dept;
}   
<!-- 
    場景一:
        查詢Employee的同時查詢員工對應的部門
        Employee===Department
        一個員工有與之對應的部門信息;
        id  last_name  gender    d_id     did  dept_name (private Department dept;)
     -->


    <!--
        聯合查詢:級聯屬性封裝結果集
      -->
    <resultMap type="com.mybatis.bean.Employee" id="MyDifEmp">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="did" property="dept.id"/>
        <result column="dept_name" property="dept.departmentName"/>
    </resultMap>
<!--  public Employee getEmpAndDept(Integer id);-->
    <select id="getEmpAndDept" resultMap="MyDifEmp">
        SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
        d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d
        WHERE e.d_id=d.id AND e.id=#{id}
    </select>

2、如果javaBea裏的屬性是一個對象時,除了上述的對象名.屬性名之外還可以使用 association指定聯合的javaBean對象,eg:

    <!-- 
        使用association定義關聯的單個對象的封裝規則;
     -->
     <resultMap type="com.mybatis.bean.Employee" id="MyDifEmp">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <!--  association可以指定聯合的javaBean對象
        property="dept":指定哪個屬性是聯合的對象
        javaType:指定這個屬性對象的類型[不能省略]
        -->
        <association property="dept" javaType="com.mybatis.bean.Department">
           <id column="d_id" property="id"/>
           <resutl column="dept_name" property="departmentName"/>
        </association>

    </resultMap>
    <!--  public Employee getEmpAndDept(Integer id);-->
    <select id="getEmpAndDept" resultMap="MyDifEmp">
        SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
        d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d
        WHERE e.d_id=d.id AND e.id=#{id}
    </select>

3、使用association進行分步查詢

    <!-- 使用association進行分步查詢:
        1、先按照員工id查詢員工信息
        2、根據查詢員工信息中的d_id值去部門表查出部門信息
        3、部門設置到員工中;
     -->

     <!--  id  last_name  email   gender    d_id   -->
     <resultMap type="com.mybatis.bean.Employee" id="MyEmpByStep">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <!-- association定義關聯對象的封裝規則
            select:表明當前屬性是調用select指定的方法查出的結果
            column:指定將哪一列的值傳給這個方法

            流程:使用select指定的方法(傳入column指定的這列參數的值)查出對象,並封裝給property指定的屬性
         -->
        <association property="dept"  select="com.mybatis.dao.DepartmentMapper.getDeptById" 
        column="d_id">
        </association>
    </resultMap>
    <!--  public Employee getEmpAndDept(Integer id);-->
    <select id="getEmpByIdStep" resultMap="MyEmpByStep">
        SELECT * FROM tbl_employee WHERE id=#{id}
    </select>
public class Department {

    private Integer id;
    private String departmentName;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.dao.DepartmentMapper">
    <!--public Department getDeptById(Integer id);  -->
    <select id="getDeptById" resultType="com.mybatis.bean.Department">
        select id,dept_name departmentName from tbl_dept where id=#{id}
    </select>
</mapper>

注:第三種方式使用association分部查詢可以實現延遲加載。即爲使用的時候才調用查詢,不使用的時候,即不調用,節省資源。例如,上述的分部查詢,如果不使用dept這個對象屬性的,第三次的查詢則不會被調用 。此時要使用setting裏的lazyLoadingEnabled和aggressiveLazyLoading配置進行實現:

<settings>
        <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
        <setting name="jdbcTypeForNull" value="NULL"/>
        <!--顯示的指定每個我們需要更改的配置的值,即使他是默認的。防止版本更新帶來的問題  -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

其他查詢寫法均如上,只是添加了一個 setting裏的配置項,這樣一來,在調用Employee對象時,如果不調用Department對象屬性,則其關聯的那個departemnt表的查詢就不會被啓用,如果用到了 department對象屬性,纔會調用其實分部查詢裏關聯的這個查詢,從而實現了延遲加載。

二、 collection

association是關聯一個對象,如果一個員工只能屬性一個部們,此時查詢員工作時定義一個部門對象屬性即可獲得一個員工的部門信息。然而一個部門裏會有很多的員工,在查詢部門時,想查詢其中所有的員工是就要定義一個集合了,對象屬性是實現的不了的,因爲是一對多的關係,現在就來說下resultMap裏怎麼定義集體:

<!-- 
    javaBean:
    public class Department {
            private Integer id;
            private String departmentName;
            private List<Employee> emps;
       sql查詢出的列字段:
      did  dept_name  ||  eid  last_name  email   gender  
     -->
    <!--嵌套結果集的方式,使用collection標籤定義關聯的集合類型的屬性封裝規則  -->
    <resultMap type="com.mybatis.bean.Department" id="MyDept">
        <id column="did" property="id"/>
        <result column="dept_name" property="departmentName"/>
        <!-- 
            collection定義關聯集合類型的屬性的封裝規則 
            ofType:指定集合裏面元素的類型
        -->
        <collection property="emps" ofType="com.mybatis.bean.Employee">
            <!-- 定義這個集合中元素的封裝規則 -->
            <id column="eid" property="id"/>
            <result column="last_name" property="lastName"/>
            <result column="email" property="email"/>
            <result column="gender" property="gender"/>
        </collection>
    </resultMap>
    <!-- public Department getDeptByIdPlus(Integer id); -->
    <select id="getDeptByIdPlus" resultMap="MyDept">
        SELECT d.id did,d.dept_name dept_name,
                e.id eid,e.last_name last_name,e.email email,e.gender gender
        FROM tbl_dept d
        LEFT JOIN tbl_employee e
        ON d.id=e.d_id
        WHERE d.id=#{id}
    </select>

colledtion分步查詢

<!-- collection:分段查詢 -->
    <resultMap type="com.mybatis.bean.Department" id="MyDeptStep">
        <id column="id" property="id"/>
        <id column="dept_name" property="departmentName"/>
        <collection property="emps" 
            select="com.atguigu.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
            column="{deptId=id}" fetchType="lazy"></collection>
    </resultMap>
    <!-- public Department getDeptByIdStep(Integer id); -->
    <select id="getDeptByIdStep" resultMap="MyDeptStep">
        select id,dept_name from tbl_dept where id=#{id}
    </select>

com.mybatis.bean.Department此爲一個查詢員工的sql:

    <!-- 
    場景二:
        查詢部門的時候將部門對應的所有員工信息也查詢出來:註釋在DepartmentMapper.xml中
     -->
    <!-- public List<Employee> getEmpsByDeptId(Integer deptId); -->
    <select id="getEmpsByDeptId" resultType="com.atguigu.mybatis.bean.Employee">
        select * from tbl_employee where d_id=#{deptId}
    </select>

注:也可以是按需加載,寫法同上用setting的lazyLoadingEnabled和aggressiveLazyLoading控制
association和collection中都會有column,如果只有一個參數數,那可以看association裏的寫法則爲:

<association property="dept" javaType="com.mybatis.bean.Department">
           <id column="d_id" property="id"/>
           <resutl column="dept_name" property="departmentName"/>
        </association>

如果查詢需要多個參數時,多列的值傳遞過去:將多列的值封裝map傳遞,如collection裏的寫法:

<!-- 擴展:多列的值傳遞過去:
            將多列的值封裝map傳遞;
            column="{key1=column1,key2=column2}"
        fetchType="lazy":表示使用延遲加載;如果全局配置文件裏開啓了延遲加載,相讓這個立即加載便可以用這個fetchType控制
                - lazy:延遲
                - eager:立即
                -
     -->
<resultMap type="com.mybatis.bean.Department" id="MyDeptStep">
        <id column="id" property="id"/>
        <id column="dept_name" property="departmentName"/>
        <collection property="emps" 
            select="com.atguigu.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
            column="{deptId=id}" fetchType="lazy"></collection>
    </resultMap>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章