淺析Mybatis的resultMap的用法以及關聯結果集映射


一、resultType

  resultType 可以把查詢結果封裝到 pojo 類型中,但必須 pojo 類的屬性名和查詢到的數據庫表的字段名一致。也就是說一般數據庫字段名喜歡用下划線類型:user_id、而實體類通常是用駝峰 userId。如果這樣子那么就對不上了,怎么辦呢?

  如果 sql 查詢到的字段與 pojo 的屬性名不一致,則需要使用 resultMap 將字段名和屬性名對應起來,進行手動配置封裝,將結果映射到pojo中。

二、resultMap用法

  resultMap是Mybatis最強大的元素,它可以將查詢到的復雜數據(比如查詢到幾個表中數據)映射到一個結果集當中。

  resultMap包含的元素:

<!--column不做限制,可以為任意表的字段,而property須為type 定義的pojo屬性-->
<resultMap id="唯一的標識" type="映射的pojo對象">
  <id column="表的主鍵字段,或者可以為查詢語句中的別名字段" 
  jdbcType
="字段類型"
  property
="映射pojo對象的主鍵屬性" /> <result column="表的一個字段(可以為任意表的一個字段)"
  jdbcType
="字段類型"
  property
="映射到pojo對象的一個屬性(須為type定義的pojo對象中的一個屬性)"/> <association property="pojo的一個對象屬性" javaType="pojo關聯的pojo對象"> <id column="關聯pojo對象對應表的主鍵字段" jdbcType="字段類型" property="關聯pojo對象的主席屬性"/> <result column="任意表的字段" jdbcType="字段類型" property="關聯pojo對象的屬性"/> </association> <!-- 集合中的property須為oftype定義的pojo對象的屬性--> <collection property="pojo的集合屬性" ofType="集合中的pojo對象"> <id column="集合中pojo對象對應的表的主鍵字段" jdbcType="字段類型" property="集合中pojo對象的主鍵屬性" /> <result column="可以為任意表的字段" jdbcType="字段類型" property="集合中的pojo對象的屬性" /> </collection> </resultMap>

  如果collection標簽是使用嵌套查詢,格式如下:

<collection column="傳遞給嵌套查詢語句的字段參數"
property="pojo對象中集合屬性"
ofType
="集合屬性中的pojo對象"
select
="嵌套的查詢語句" > </collection>

  注意:<collection>標簽中的column:要傳遞給select查詢語句的參數,如果傳遞多個參數,格式為column= ” {參數名1=表字段1,參數名2=表字段2} ;

  resultMap 可以實現將查詢結果映射為復雜類型的 pojo,比如在查詢結果映射對象中包括pojo和list實現一對一查詢和一對多查詢。

1、先在Mapper文件中,配置基本的sql語句

    <!-- 查詢所有的訂單數據 -->
    <!-- resultMap:填入配置的resultMap標簽的id值 -->
    <select id="queryOrderAll" resultMap="orderResultMap"> SELECT id, user_id, number, createtime, note FROM `order` </select>

2、配置resultMap標簽,映射不同的字段和屬性名

  此處的 id 就對應上面的 resultMap,此處的 type 就對應你設置的實體類的 pojo

   <!-- resultMap最終還是要將結果映射到pojo上,type就是指定映射到哪一個pojo -->
    <!-- id:設置ResultMap的id -->
    <resultMap type="order" id="orderResultMap">
        <!-- 定義主鍵 ,非常重要。如果是多個字段,則定義多個id -->
        <!-- property:主鍵在pojo中的屬性名 -->
        <!-- column:主鍵在數據庫中的列名 -->
        <id property="id" column="id" />

        <!-- 定義普通屬性 -->
        <result property="userId" column="user_id" />
        <result property="number" column="number" />
        <result property="createTime" column="createtime" />
        <result property="note" column="note" />
    </resultMap>

  結果就可以封裝到 pojo 中

三、使用resultMap進行關聯查詢

1、一對一查詢

  一對一數據模型:訂單用戶

  一個訂單信息只會是一個人下的訂單,所以從查詢訂單信息出發關聯查詢用戶信息為一對一查詢。

  如果從用戶信息出發查詢用戶下的訂單信息則為一對多查詢,因為一個用戶可以下多個訂單。

(1)改造pojo類

  在訂單類中添加User屬性,User屬性是一個引用類型,用於存儲關聯查詢的用戶信息,因為關聯關系是一對一,所以只需要添加單個屬性即可

(2)配置Mapper.xml配置文件

  OrderMapper.xml — 先使用id和result屬性,映射order類的結果集,然后在使用association映射關聯對象User的結果集

<resultMap type="order" id="orderUserResultMap">
    <id property="id" column="id" />
    <result property="userId" column="user_id" />
    <result property="number" column="number" />
    <result property="createTime" column="createtime" />
    <result property="note" column="note" />

    <!-- association :配置一對一屬性 -->
    <!-- property:order里面的User屬性名 -->
        <!-- javaType:屬性類型 -->
    <association property="user" javaType="user">
        <!-- id:聲明主鍵,表示user_id是關聯查詢對象的唯一標識-->
        <id property="id" column="user_id" />
        <result property="username" column="username" />
        <result property="address" column="address" />
    </association>

</resultMap>
<!-- 一對一關聯,查詢訂單,訂單內部包含用戶屬性 -->
<select id="queryOrderUserResultMap" resultMap="orderUserResultMap"> SELECT o.id, o.user_id, o.number, o.createtime, o.note, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id </select>
@Test public void testQueryOrderUserResultMap() { // mybatis和spring整合,整合之后,交給spring管理
    SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 創建Mapper接口的動態代理對象,整合之后,交給spring管理
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper執行根據條件查詢用戶,結果封裝到Order類中
    List<Order> list = userMapper.queryOrderUserResultMap(); for (Order o : list) { System.out.println(o); } // mybatis和spring整合,整合之后,交給spring管理
 sqlSession.close(); }

2、一對多查詢

  查詢所有用戶信息及相關訂單。

(1)修改pojo類,在pojo類添加訂單集合屬性

(2)修改UserMapper.xml配置文件

  先使用id和result配置映射User類的結果,然后使用一對多關系的collection標簽配置Order結果

<resultMap type="user" id="userOrderResultMap">
    <id property="id" column="id" />
    <result property="username" column="username" />
    <result property="birthday" column="birthday" />
    <result property="sex" column="sex" />
    <result property="address" column="address" />

    <!-- 配置一對多的關系 property:填寫pojo類中集合類類屬性的名稱 javaType:填寫集合類型的名稱 -->
    <collection property="orders" javaType="list" ofType="order">
        <!-- 配置主鍵,是關聯Order的唯一標識 -->
        <id property="id" column="oid" />
        <result property="number" column="number" />
        <result property="createtime" column="createtime" />
        <result property="note" column="note" />
    </collection>
</resultMap>

<!-- 一對多關聯,查詢訂單同時查詢該用戶下的訂單 -->
<select id="queryUserOrder" resultMap="userOrderResultMap"> SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id </select>

四、實例介紹resultMap的用法

1、創建商品pojo對象

public class TShopSku { 
    private Long id;
    private String skuName;
    private Long categoryId;
  ......
}

  對應的resultMap

<resultMap id="BaseResultMap" type="com.meikai.shop.entity.TShopSku">
    <id column="ID" jdbcType="BIGINT" property="id" />
    <result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
    <result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
</resultMap> 

2、商品pojo類添加屬性集合:

  一個商品會有一些屬性,現在需要將查詢出的商品屬性添加到商品對象中,首先需要在原商品pojo類的基礎上中添加屬性的集合:

  // 屬性集合
    private List<TShopAttribute> attributes; 
    public List<TShopAttribute> getAttributes() { return attributes; }
     public void setAttributes(List<TShopAttribute> attributes) { this.attributes = attributes; }

  將Collection標簽添加到resultMap中,這里有兩種方式:

1、嵌套結果:對應的resultMap:

<resultMap id="BasePlusResultMap" type="com.meikai.shop.entity.TShopSku">
    <id column="ID" jdbcType="BIGINT" property="id" />
    <result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
    <result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
    <collection property="attributes" ofType="com.meikai.shop.entity.TShopAttribute" > 
        <id column="AttributeID" jdbcType="BIGINT" property="id" />
        <result column="attribute_NAME" jdbcType="VARCHAR" property="attributeName" />
    </collection>
</resultMap> // 查詢語句 <select id="getById" resultMap="basePlusResultMap"> select s.ID,s.SKU_NAME,s.CATEGORY_ID,a.ID,a.ATTRIBUTE_NAME from t_shop_sku s,t_shop_attribute a where s.ID =a.SKU_ID and s.ID = #{id,jdbcType =BIGINT}; </select>

2、關聯的嵌套查詢(在collection中添加select屬性):

  商品結果集映射resultMap:

<resultMap id="BasePlusResultMap" type="com.meikai.shop.entity.TShopSku">
    <id column="ID" jdbcType="BIGINT" property="id" />
    <result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
    <result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
    <collection column="{skuId=ID}" property="attributes" ofType="com.meikai.shop.entity.TShopAttribute" select="getAttribute" > 
    </collection>
</resultMap>

  collection的select會執行下面的查詢屬性語句:

<select id="getAttribute" resultMap="AttributeResultMap"> select a.ID,s.ATTRIBUTE_NAME from t_shop_attribute a where a.ID = #{skuId,jdbcType =BIGINT}; </select>

  屬性結果集映射:

<resultMap id="AttributeResultMap" type="com.meikai.shop.entity.TShopAttribute">
    <id column="ID" jdbcType="BIGINT" property="id" />
    <result column="ATTRIBUTE_NAME" jdbcType="VARCHAR" property="attributeName" />
</resultMap>

  BasePlusResultMap包含了屬性查詢語句的Collection,所以通過下面的查詢商品語句就可獲得商品以及其包含的屬性集合:

<select id="getById" resultMap="BasePlusResultMap"> select s.ID,s.SKU_NAME,s.CATEGORY_ID from t_shop_sku s where s.ID = #{id,jdbcType =BIGINT}; </select>


免責聲明!

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



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