Mybatis原始碼分析--返回值ResultType和ResultMap
阿新 • • 發佈:2019-02-05
這一篇部落格我們來介紹一下Mybatis執行sql語句返回的結果值的到實體物件的對映機制。首先ResultType和ResultMap的使用方式是不同的。
ResultType的使用方式:
resultType的值為實體類
<select id="getUser" parameterType="int" resultType="com.tianjunwei.learn.learn1.entity.User">
select * from users where id=#{id}
</select>
ResultMap的使用方式:首先要定義resultMap的對應關係
接下來直接使用id值resultMap="user"<resultMap type="com.tianjunwei.learn.learn1.entity.User" id="user"> <id column="id" property="id" javaType="int" jdbcType="INTEGER"></id> <result column="name" property="names" javaType="string" jdbcType=VARCHAR/> <result column="age" property="age" javaType="int" jdbcType="INTEGER"/> </resultMap>
<select id="getById" parameterType="int" resultMap="user">
select * from users where id=#{id} and 1=1
</select>
以上就完成了resultType和resultMap的使用。其實mybatis的預設實現機制是首先會自動使用resultType模式,當表中的欄位值和實體中的名稱不一致時再使用ResultMap方式,如上面的實體User中的names和表中欄位name中的對應關係,所以使用resultType方式實體類中User的names屬性值為空,而使用resultMap方式實體類中就會有值。
當強制使用resultMap而不是ResultType是需要進行如下配置:增加了autoMapping=false,預設值為null
<resultMap type="com.tianjunwei.learn.learn1.entity.User" id="user" autoMapping="false">
<id column="id" property="id" javaType="int" jdbcType="INTEGER"></id>
<result column="name" property="names" javaType="string" jdbcType="VARCHAR"/>
<result column="age" property="age" javaType="int" jdbcType="INTEGER"/>
</resultMap>
接下來我們介紹一下其實現機制:
其具體實現是在DefaultResultSetHandler中,在獲取每行資料時會根據resultType或者resultMap來給物件賦值,返回resultObject。
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
final ResultLoaderMap lazyLoader = new ResultLoaderMap();
Object resultObject = createResultObject(rsw, resultMap, lazyLoader, null);
if (resultObject != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
final MetaObject metaObject = configuration.newMetaObject(resultObject);
boolean foundValues = !resultMap.getConstructorResultMappings().isEmpty();
//判斷是否可以使用resultType,如果不做任何額外設定,返回true
if (shouldApplyAutomaticMappings(resultMap, false)) {
foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;
}
//使用resultMap方式
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
foundValues = lazyLoader.size() > 0 || foundValues;
resultObject = foundValues ? resultObject : null;
return resultObject;
}
return resultObject;
}