使用 resultMap 實現高級結果集映射


resultMap 的基本配置項

  屬性

    id 屬性:resultMap 的唯一標識,此 id 值用於 select 元素 resultMap 屬性的引用。
    type 屬性:表示該 resultMap 的映射結果類型(通常是 Java 實體類)。

  子節點

    id 子節點:一般對應數據庫中該行的主鍵 id,設置此項可以提升 MyBatis 性能。
    result 子節點:映射到 JavaBean 的某個 “簡單類型” 屬性,如基礎數據類型、包裝類等。

  子節點屬性

    column 屬性:表示從數據庫中查詢的字段名或別名。

    property 屬性:表示查詢出來的字段對應的值賦給實體對象的哪個屬性。

 

  說明:子節點 id 和 result 均可實現最基本的結果集映射,將列映射到簡單數據類型的屬性。這兩者唯一不同的是:在比較對象實例時 id 將作為結果集的標識屬性。這有助於提高總體性能,特別是應用緩存和嵌套結果映射的時候。而若要實現高級結果映射,就需要學習下面兩個配置項: association 和 collection。

 

ssociation

  association:映射到 JavaBean 的某個 “復雜類型” 屬性,比如 JavaBean 類,即 JavaBean 內部嵌套一個復雜數據類型(JavaBean)屬性,這種情況就屬於復雜類型的關聯。但是需要注意: association 僅處理一對一的關聯關系

  ssociation 的屬性

    javaType 屬性:完整 Java 類名或者別名。若映射到一個 JavaBean,則 MyBatis 通常會自行檢測到其類型;若映射到一個 HashMap ,則應該明確指定 javaType,來確保所需行為。

     property 屬性:映射數據庫列的實體對象的屬性。

  ssociation 的子元素

    id 子元素:一般對應數據庫中該行的主鍵 id,設置此項可以提升 MyBatis 性能。

    result 子元素
        ◆ property 屬性:映射數據庫列的實體對象的屬性。
        ◆ column 屬性:數據庫列名或別名。

 

  說明
     (1)在做結果映射的過程中,需要注意:要確保所有的列名都是唯一且無歧義的。
     (2)id 子元素在嵌套結果映射中扮演了非常重要的角色,應該指定一個或者多個屬性來唯一標識這個結果集。實際上,即便沒有指定 id, MyBatis 也會工作,但是會導致嚴重的性能開銷,所以最好選擇盡量少的屬性來唯一標識結果,主鍵或者聯合主鍵均可。

 

 案例根據用戶角色 id 獲取該角色下的用戶列表

(1)修改 User 類,增加角色屬性 (private Role role) ,並增加相應的 getter 和 setter 方法。

      private Role role;   //復雜類型:用戶角色
    
      public Role getRole() {
          return role;
      }
      public void setRole(Role role) {
          this.role = role;
      }

(2)在 UserMapper.java 接口里增加根據角色 id 獲取用戶列表的方法。

    /**
     * 根據用戶角色 id 獲取該角色下的用戶列表
     * @param roleId 用戶角色 id
     * @return
     */
    public List<User> getUserListByRoleId(@Param("uRole")int roleId);

(3)在 UserMapper.xml 里增加 id 為 getUserListByRoleId 的查詢語句,該查詢語句返回類型為 resultMap,並且外部引用的 resultMap 的類型為 User。
   說明:由於 User 對象內嵌 JavaBean 對象(role),因此需要使用 association 來實現結果映射。

    <!--根據用戶角色 id 獲取該角色下的用戶列表 -->
    <select id="getUserListByRoleId" resultMap="userRoleResult"
        parameterType="int">
        SELECT u.* , r.id AS r_id , r.`roleCode` , r.`roleName`
        FROM `smbms_user` AS u,`smbms_role` AS r
        WHERE u.`userRole`=#{uRole} AND u.`userRole`=r.`id`
    </select>

    <resultMap type="user" id="userRoleResult">
        <id property="id" column="id" />
        <result property="userCode" column="userCode" />
        <result property="userName" column="userName" />
        <result property="userRole" column="userRole" />

        <association property="role" javaType="role">
            <id property="id" column="r_id" />
            <result property="roleCode" column="roleCode" />
            <result property="roleName" column="roleName" />
        </association>
    </resultMap>4)單元測試類使用 Junit 測試   

   @Test //測試根據用戶角色 id 獲取該角色下的用戶列表
    public void testGetUserListByRoleId(){
          List<User> userList=new ArrayList<User>();
          userList=session.getMapper(UserMapper.class).getUserListByRoleId(2);
            
          //打印 用戶角色 id 為 2 的用戶有幾個
          System.out.println("userList 的長度:"+userList.size());
          //使用 resultMap 實現復雜類型關聯
          for (User user : userList) {
                System.out.println("User:"+user.getUserName()+
                "---Role:"+user.getRole().getId()+"---"+user.getRole().getRoleCode()+"---"+user.getRole().getRoleName());
          }
    }

 

 復用 association 的結果映射

  association 提供了的另一個屬性: resultMap 通過這個屬性可以擴展一個 resultMap 來進行聯合映射,這樣就可以使 role 結果映射重復使用。特別適合 association 的結果映射比較多的情況,當然,若不需要重用,也可按照上面代碼的寫法,直接嵌套這個聯合結果映射,根據具體業務而定。

//使用 resultMap 屬性完成 association 的 role 映射結果的復用,修改 UserMapper.xml ,association 子節點上增加 resultMap 屬性來引用外部的 resultMap。

<!--根據用戶角色 id 獲取該角色下的用戶列表 -->
    <select id="getUserListByRoleId" resultMap="userRoleResult"
        parameterType="int">
        SELECT u.* , r.id AS r_id , r.`roleCode` , r.`roleName`
        FROM `smbms_user` AS u,`smbms_role` AS r
        WHERE u.`userRole`=#{uRole} AND u.`userRole`=r.`id`
    </select>

    <resultMap type="user" id="userRoleResult">
        <id property="id" column="id" />
        <result property="userCode" column="userCode" />
        <result property="userName" column="userName" />
        <result property="userRole" column="userRole" />

        <association property="role" javaType="role" resultMap="roleResult" />
    </resultMap>
    
    <resultMap type="role" id="roleResult">
            <id property="id" column="r_id"/>
            <result property="roleCode" column="roleCode"/>
            <result property="roleName" column="roleName"/>
    </resultMap>

 

collection

  collection 元素的作用和 association 元素的作用差不多一樣,事實上,它們非常類似,也是映射到 JavaBean 的某個 “復雜類型” 屬性,只不過這個屬性是一個集合列表,即 JavaBean 內部嵌套一個復雜數據類型(集合)屬性。和使用 association 元素一樣,我付使用嵌套查詢,或者從連接中嵌套結果集。

  collection 的屬性

    ofType 屬性:完整 Java 類名或者別名,即集合所包含的類型。

    property 屬性:映射數據庫列的實體對象的屬性。

  collection 的子元素

    id 子元素:一般對應數據庫中該行的主鍵 id,設置此項可以提升 MyBatis 性能。

    result 子元素
        ◆ property 屬性:映射數據庫列的實體對象的屬性。
        ◆ column 屬性:數據庫列名或別名。

 

 案例獲取指定用戶的相關信息和地址列表

(1)在 User 實體類中,增加地址列表屬性 private List<Address> addressList ,並增加相應的 getter 和 setter 方法。User 對象內部嵌套了一個復雜數據類型的屬性,addressList。

       private List<Address> addressList;  //用戶地址列表
    
       public List<Address> getAddressList() {
           return addressList;
       }
       public void setAddressList(List<Address> addressList) {
           this.addressList = addressList;
       }

(2)在 UserMapper.java 接口中增加根據用戶 id 獲取用戶信息以及地址列表的方法。

       /**
     * 根據用戶 id 獲取指定用戶的相關信息和地址列表
     * @param userId 用戶 id
     * @return
     */
    public List<User> getAddressListByUserId(@Param("id")int userId);

(3)在 UserMapper.xml 中增加 id 為 getAddressListByUserId 的查詢語句,該 select 查詢語句返回類型為 resultMap ,並且引用外部的 resultMap 的類型為 User。由於 User 對象內嵌集合對象(addressList) ,因此需要使用 collection 來實現結果映射。

<!--根據用戶 id 獲取指定用戶的相關信息和地址列表-->
    <select id="getAddressListByUserId" resultMap="userAddressResult" parameterType="int">
            SELECT u.*,a.`id` AS a_id ,a.`contact`,a.`addressDesc`,a.`postCode`,a.`tel` 
            FROM `smbms_user` u ,`smbms_address` a 
            WHERE u.`id`=a.`userId` AND u.`id`=#{id}
    </select>
    
    <resultMap type="user" id="userAddressResult">
            <id property="id" column="id"/>
            <result property="userCode" column="userCode"/>
            <result property="userName" column="userName"/>
            
        <collection property="addressList" ofType="address">
            <id property="id" column="a_id"/>
            <result property="postCode" column="postCode"/>
            <result property="tel" column="tel"/>
            <result property="contact" column="contact"/>
            <result property="addressDesc" column="addressDesc"/>
        </collection>
    </resultMap>4)單元測試類使用 Junit 測試     

@Test //測試根據用戶 id 獲取指定用戶的相關信息和地址列表
    public void testGetAddressListByUserId() {
        List<User> userList = new ArrayList<User>();
        userList = session.getMapper(UserMapper.class).getAddressListByUserId(1);

        for (User user : userList) {
            System.out.println("userList(include:addresslist) =====> userCode: " + user.getUserCode() + ", userName: "
                    + user.getUserName());
            for (Address address : user.getAddressList()) {
                System.out.println("address ----> id: " + address.getId() + ", contact: " + address.getContact()
                        + ", addressDesc: " + address.getAddressDesc() + ", tel: " + address.getTel() + ", postCode: "
                        + address.getPostCode());
            }
        }
   }    

復用 collection 的結果映射

  提取相應代碼到一個 resultMap 中,給 collection 增加 resultMap 屬性進行外部引用即可。
   <!--根據用戶 id 獲取指定用戶的相關信息和地址列表-->
    <select id="getAddressListByUserId" resultMap="userAddressResult" parameterType="int">
            SELECT u.*,a.`id` AS a_id ,a.`contact`,a.`addressDesc`,a.`postCode`,a.`tel` 
            FROM `smbms_user` u ,`smbms_address` a 
            WHERE u.`id`=a.`userId` AND u.`id`=#{id}
    </select>
    
    <resultMap type="user" id="userAddressResult">
            <id property="id" column="id"/>
            <result property="userCode" column="userCode"/>
            <result property="userName" column="userName"/>
            
        <collection property="addressList" ofType="address" resultMap="addressResult"/>
    </resultMap>
    
    <resultMap type="address" id="addressResult">
            <id property="id" column="a_id"/>
            <result property="postCode" column="postCode"/>
            <result property="tel" column="tel"/>
            <result property="contact" column="contact"/>
            <result property="addressDesc" column="addressDesc"/>
    </resultMap>

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM