autoMapping和autoMappingBehavior的區別及說明

autoMapping和autoMappingBehavior的區別

autoMappingBehavior

mybatis核心配置文件中settings中配置,指定 MyBatis 應如何自動映射列到字段或屬性。 NONE 表示取消自動映射;PARTIAL 隻會自動映射沒有定義嵌套結果集映射的結果集。 FULL 會自動映射任意復雜的結果集(無論是否嵌套)。默認是partial,這是一種全局設置

autoMapping

在resultMap或者association,collections中使用,是一個局部開關,開啟後會自動設置嵌套查詢中的屬性,局部開關優先級大於全部開關,當全部開關開啟FULL映射時,局部開關關閉,這時候仍然不會進行映射。

例子

配置信息,mybatis的Settings全部為默認配置,我們測試局部自動映射的結果

    <select id="findCustomerByIdResultMap" parameterType="int" resultMap="CustomerResultMap">
    SELECT
        id,
        username,
        jobs,
        phone,
        idCard.cardId as cardId,
        idcard.address as address
        FROM
        t_customer ,
        idcard
        WHERE t_customer.cardId=idcard.cardId and t_customer.id=#{id}
    </select>
    
    <resultMap type="cn.edu.huel.po.Customer" id="CustomerResultMap">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="jobs" property="jobs"/>
    <result column="phone" property="phone"/>
    <association  property="card"  javaType="cn.edu.huel.po.IdCard">
        <id column="cardId" property="cardId"/>
        <result column="address" property="address"/>
    </association>

測試結果

DEBUG [main] – ==>  Preparing: SELECT id, username, jobs, phone, idCard.cardId as cardId, idcard.address as address FROM t_customer , idcard WHERE t_customer.cardId=idcard.cardId and t_customer.id=? 
DEBUG [main] – ==> Parameters: 2(Integer)
DEBUG [main] – <==      Total: 1
Customer [id=2, username=李四, jobs=采購, phone=222, card=IdCard [cardId=2222, address=安陽]]

去掉restult,不開啟autoMapping

<select id="findCustomerByIdResultMap" parameterType="int" resultMap="CustomerResultMap">
    SELECT
        id,
        username,
        jobs,
        phone,
        idCard.cardId as cardId,
        idcard.address as address
        FROM
        t_customer ,
        idcard
        WHERE t_customer.cardId=idcard.cardId and t_customer.id=#{id}
    </select>
    
    <resultMap type="cn.edu.huel.po.Customer" id="CustomerResultMap">
    <id column="id" property="id"/>
    <association  property="card"  javaType="cn.edu.huel.po.IdCard">
        <id column="cardId" property="cardId"/>
    </association>
    </resultMap>

結果,可以看出在嵌套查詢中,mybatis默認設置嵌套查詢不自動映射,必須的有result

DEBUG [main] – ==>  Preparing: SELECT id, username, jobs, phone, idCard.cardId as cardId, idcard.address as address FROM t_customer , idcard WHERE t_customer.cardId=idcard.cardId and t_customer.id=? 
DEBUG [main] – ==> Parameters: 2(Integer)
DEBUG [main] – <==      Total: 1
Customer [id=2, username=null, jobs=null, phone=null, card=IdCard [cardId=2222, address=null]]

加上autoMapping為ture進行測試

<select id="findCustomerByIdResultMap" parameterType="int" resultMap="CustomerResultMap">
    SELECT
        id,
        username,
        jobs,
        phone,
        idCard.cardId as cardId,
        idcard.address as address
        FROM
        t_customer ,
        idcard
        WHERE t_customer.cardId=idcard.cardId and t_customer.id=#{id}
    </select>
    
    <resultMap type="cn.edu.huel.po.Customer" autoMapping="true" id="CustomerResultMap">
        <id column="id" property="id"/>
        <association  property="card" autoMapping="true"  javaType="cn.edu.huel.po.IdCard">
            <id column="cardId" property="cardId"/>
        </association>
    </resultMap>

結果,沒有result,結果照樣映射

DEBUG [main] – ==>  Preparing: SELECT id, username, jobs, phone, idCard.cardId as cardId, idcard.address as address FROM t_customer , idcard WHERE t_customer.cardId=idcard.cardId and t_customer.id=? 
DEBUG [main] – ==> Parameters: 2(Integer)
DEBUG [main] – <==      Total: 1
Customer [id=2, username=李四, jobs=采購, phone=222, card=IdCard [cardId=2222, address=安陽]]

小結一下

autoMappingBehavior是<settings>裡面的,是全局總開關。autoMapping是<resultMap>裡面的,是局部select語句映射開關。

局部開關優先級大於全局開關。

如上resultMap配置瞭autoMapping, 那麼mybatis會自動把查詢出來的name、id、cartid都賦值給customer, 如果autoMappng設為false, 則不會自動映射, 需要你在resultMap中手動配置result,它的作用在collection和association標簽中作用是一樣的。

此外, 配置autoMapping這個屬性的優先級高於autoMappingBehavior, 也就是即使你autoMappingBehavior配置為FULL, 但是autoMapping配置為false, 那麼依舊不會自動映射。

在嵌套影射中通常會同時配置上columnPrefix屬性, 這樣的話可以在一定程度上避免因為實體屬性名相同導致mybatis無法正確賦值的問題。

mybaits collection使用autoMapping註意點

mybaits 在resultMap 中使用autoMapping 時出現以下情況

<collection property="persons"    ofType="io.ztx.infra.dto.PersonDTO" autoMapping = "true">
    <id property="id" column="person_id"/>
    <result property="name" column="person_name"/>
</collection>

在collection 中設置瞭autoMapping,也指定瞭映射字段的列和屬性名,會出現關聯查詢時collection返回是null,會直接映射成空對象

  id : 1,
  persons: [
     {
      personId:null,
      personName:null
     }
  ]

實驗幾次後發現去掉autoMaping就不會出現這種情況

  id : 1,
  persons:[]

還有一種方法是把<result/> 換成<id/> 同樣能夠解決

<collection property="persons"    ofType="io.ztx.infra.dto.PersonDTO" autoMapping = "true">
    <id property="id" column="person_id"/>
    <id property="name" column="person_name"/>
</collection>

一般不會出現同時開啟autoMapping 又使用指定列和類屬性方式的二者取其一就行。

自動映射可以通過columnPrefix指定前綴以及返回在sql中設置別名的方式來映射。這樣就可以用手動去collection中寫<id/> <resule/>瞭。

<collection property="persons"    ofType="io.ztx.infra.dto.PersonDTO" autoMapping = "true" columnPrefix="p_">
</collection>
select 
    a.id as id,
    p.id as p_id,
    p.name as p_name
    fron A a
    left Join person p on p.id = a.pid

註意:SQL中映射的別名必須以設置好的前綴相同,同時保證別名和類屬性名符合映射規則。

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: