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。
推薦閱讀:
- Mybatis一對多查詢列表屬性處理示例詳解
- Mybatis加載策略的實現方法
- 解決mybatis一對多查詢resultMap隻返回瞭一條記錄問題
- 關於Mybatis使用collection分頁問題
- java工程師進階之MyBatis延遲加載的使用