mybatis resultmap 如何為對象賦值的調(diào)用順序
resultmap 為對象賦值的調(diào)用順序
寫了一個mybatis的mapper映射文件,
java bean定義如下
public class GroupCourseResult extends GroupResult { private String cid; private String cname; public GroupCourseResult(int stuschool, int nian, String stuclass, String cid, String cname) { super(stuschool, nian, stuclass); this.cid = cid; this.cname = cname; } public String getCid() { return cid; } public void setCid(String cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } }
部分mybatis映射文件如下
<select id="selectFailedCourseRationByGroupIdAndCourseName" resultType="GroupCourseResult"> ? ? ? ... ? </select>
實體類中的屬性名和查詢的列名完全匹配,但是沒有查詢stuclass,則封裝后的實體類中的stuclass屬性應(yīng)該為空。
然而程序運行后,stuclass屬性不僅不為空,還與cname完全相同,百思不得其解,故翻了翻mybatis的源碼。
在mybatis中的DefaultResultSetHandler類中,
createResultObject方法的代碼如下
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix) throws SQLException { final Class<?> resultType = resultMap.getType(); final MetaClass metaType = MetaClass.forClass(resultType, reflectorFactory); final List<ResultMapping> constructorMappings = resultMap.getConstructorResultMappings(); if (hasTypeHandlerForResultObject(rsw, resultType)) { return createPrimitiveResultObject(rsw, resultMap, columnPrefix); } else if (!constructorMappings.isEmpty()) { return createParameterizedResultObject(rsw, resultType, constructorMappings, constructorArgTypes, constructorArgs, columnPrefix); } else if (resultType.isInterface() || metaType.hasDefaultConstructor()) { return objectFactory.create(resultType); } else if (shouldApplyAutomaticMappings(resultMap, false)) { return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs); } throw new ExecutorException("Do not know how to create an instance of " + resultType); }
經(jīng)過調(diào)試發(fā)現(xiàn),mybatis會先查找該javabean有無默認構(gòu)造方法,如果有則采用設(shè)值注入,若沒有,則根據(jù)javabean的有參構(gòu)造方法進行設(shè)值,而在8以前的jdk版本中,我們利用反射只能獲取到參數(shù)類型,不能獲取到參數(shù)名稱,這其中設(shè)值可能出現(xiàn)了匹配失誤,將cname的值同時賦給了cname和stuclass。
想要解決這個問題,只須在javabean中添加默認構(gòu)造方法即可。
使用resultMap時需注意的問題
如果是實體中是直接引用別的對象的具體參數(shù)字段,
直接用原始方式就行
<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>
如果是實體中是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 標簽來寫
<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標簽
<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中各個標簽的含義
tips:
在一個 resultMap 元素中,這些子元素出現(xiàn)的先后順序是有嚴格規(guī)定的,它們從前到后依次是:constructor–>id --> result–> association–>collection -->discriminator, 不然就會報錯。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
eclipse/IDEA配置javafx項目步驟(圖文教程)
這篇文章主要介紹了eclipse/IDEA配置javafx項目步驟(圖文教程),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03java連接hdfs ha和調(diào)用mapreduce jar示例
這篇文章主要介紹了Java API連接HDFS HA和調(diào)用MapReduce jar包,需要的朋友可以參考下2014-03-03利用synchronized實現(xiàn)線程同步的案例講解
這篇文章主要介紹了利用synchronized實現(xiàn)線程同步的案例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02javaweb 國際化:DateFormat,NumberFormat,MessageFormat,ResourceBu
本文主要介紹javaWEB國際化的知識,這里整理了詳細的資料及實現(xiàn)代碼,有興趣的小伙伴可以參考下2016-09-09Spring Cloud Gateway(讀取、修改 Request Body)的操作
這篇文章主要介紹了Spring Cloud Gateway(讀取、修改 Request Body)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12