Java?Mybatis使用resultMap時,屬性賦值順序錯誤的巨坑
Mybatis使用resultMap屬性賦值順序錯誤
今天發(fā)現(xiàn)個坑,新建的表使用生成工具生成的mapper文件和實體類后,發(fā)現(xiàn)少了個字段就又手動加了下,結(jié)果發(fā)現(xiàn)一個問題
ids是后加入的字段
@Data
@Builder
public class QueryRecordPo {
?
? ? ?//若干其他屬性....
? ? private String outputField;
? ? ?//后加的
? ? private String ids;
?
? ? //若干其他屬性
? ? //...?
}resultMap中是這樣寫的
? ? <resultMap id="BaseResultMap" type="...."> ? ? ? ? <id column="id" jdbcType="BIGINT" property="id"/> ? ? ? ? ..若干其他屬性 ? ? ? ? <result column="ids" jdbcType="VARCHAR" property="ids"/> ? ? ? ? <result column="output_field" jdbcType="VARCHAR" property="outputField"/> ? ? ? ? ..若干其他屬性 ? ? </resultMap>
可以發(fā)現(xiàn)ids加的位置是不一樣的,實體類中在outputField屬性下面,但resultMap中在其上面。然后測試數(shù)據(jù)中ids字段為null,查詢出來時卻發(fā)現(xiàn)ids的值和outputField的值是一樣的。但如果ids的字段有值,就可以正確賦值。
mybatis在生成目標(biāo)類進(jìn)行映射時,會先檢查構(gòu)造函數(shù)聲明情況,但 如果Data注解和Builder注解一塊使用的話就只會生成全屬性參數(shù)構(gòu)造函數(shù),不會有默認(rèn)無參構(gòu)造函數(shù)。全屬性構(gòu)造函數(shù)的參數(shù)順序是和類中屬性聲明順序一致的
在把數(shù)據(jù)庫字段映射到實體類的時候發(fā)現(xiàn)實體類沒有默認(rèn)無參構(gòu)造函數(shù),就會把數(shù)據(jù)庫中的字段按照全屬性構(gòu)造函數(shù)參數(shù)的順序依次賦值給實體類的屬性。但如果實體類的屬性定義順序與數(shù)據(jù)庫中字段順序不一致,就會出現(xiàn)賦值錯誤的情況。
然后再為outputField字段賦值時調(diào)用了set方法 這樣就出現(xiàn)了兩個不同名但同值的屬性。
解決辦法
1 修改屬性順序保持一致
2 為實體類加上@NoArgsConstructor和 @AllArgsConstructor注解 使其可以生成無參數(shù)構(gòu)造函數(shù)即可
之前生成時 順序都保持了一致,還真沒發(fā)現(xiàn)這個問題
Mybatis使用resultMap時需注意
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
如果是實體中是直接引用別的對象的具體參數(shù)字段,直接用原始方式就行
如果是實體中是list集合
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
<collection property="pic" ofType="string">
<result column="pic"/>
</collection>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
如果實體中引用的是別的對象,可以使用association 標(biāo)簽來寫
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
<association property="eduEducationRecord" javaType="com.ei.medical.modules.model.EduEducationRecord">
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
</association>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
如果實體中是引用的別的對象的list集合,應(yīng)該使用collection 標(biāo)簽
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
<collection property="eduEducationRecordList" ofType="com.ei.medical.modules.model.EduEducationRecord">
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
</collection>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
tips:
使用resultMap的時候,應(yīng)該直接用as后面的字段名,即自己命的名字
如果沒有使用as的話,直接使用數(shù)據(jù)庫中原本的名字
resultMap中各個標(biāo)簽的含義

tips:
在一個 resultMap 元素中,這些子元素出現(xiàn)的先后順序是有嚴(yán)格規(guī)定的,它們從前到后依次是:constructor–>id --> result–> association–>collection -->discriminator, 不然就會報錯。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中private關(guān)鍵字詳細(xì)用法實例以及解釋
這篇文章主要給大家介紹了關(guān)于Java中private關(guān)鍵字詳細(xì)用法實例以及解釋的相關(guān)資料,在Java中private是一種訪問修飾符,它可以用來控制類成員的訪問權(quán)限,文中將用法介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
詳解如何在Spring?Security中自定義權(quán)限表達(dá)式
這篇文章主要和大家詳細(xì)介紹一下如何在Spring?Security中自定義權(quán)限表達(dá)式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-07-07
SpringCloud遠(yuǎn)程服務(wù)調(diào)用實戰(zhàn)筆記
本文給大家介紹SpringCloud遠(yuǎn)程服務(wù)調(diào)用實戰(zhàn)筆記,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-11-11
Java正則表達(dá)式實現(xiàn)在文本中匹配查找換行符的方法【經(jīng)典實例】
這篇文章主要介紹了Java正則表達(dá)式實現(xiàn)在文本中匹配查找換行符的方法,結(jié)合具體實例分析了java正則匹配查找換行符的實現(xiàn)技巧與匹配模式相關(guān)操作注意事項,需要的朋友可以參考下2017-04-04

