Mybatis後果集自動映射的實例代碼。本站提示廣大學習愛好者:(Mybatis後果集自動映射的實例代碼)文章只能為提供參考,不一定能成為您想要的結果。以下是Mybatis後果集自動映射的實例代碼正文
在運用Mybatis時,有的時分我們可以不必定義resultMap,而是直接在<select>語句上指定resultType。這個時分其實就用到了Mybatis的後果集自動映射。Mybatis的自動映射默許是開啟的,有需求我們也可以將其封閉(還可以調整自動映射的戰略)。
1 Mybatis後果集自動映射
在運用Mybatis時,有的時分我們可以不必定義resultMap,而是直接在<select>語句上指定resultType。這個時分其實就用到了Mybatis的後果集自動映射。Mybatis的自動映射默許是開啟的,其在映射的時分會先把沒有在resultMap中定義字段映射的字段依照稱號相反的方式自動映射到前往類型的對應屬性上。自動映射的時分會疏忽大小寫,比方查詢語句中查詢出來了一個字段是ID,我們對應的前往類型有一個屬性id,且有一個setId()辦法,那麼id跟ID也是可以婚配的,是可以自動映射的,Mybatis就會把查詢出來的後果集中字段ID對應的值賦給前往類型對象的id屬性。
1.1 源碼剖析
關於自動映射這塊的邏輯規則可以參考Mybatis的DefaultResultSetHandler的源碼,其中心代碼如下。
private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
List<UnMappedColumAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
boolean foundValues = false;
if (autoMapping.size() > 0) {
for (UnMappedColumAutoMapping mapping : autoMapping) {
final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
if (value != null || configuration.isCallSettersOnNulls()) {
if (value != null || !mapping.primitive) {
metaObject.setValue(mapping.property, value);
}
foundValues = true;
}
}
}
return foundValues;
}
private List<UnMappedColumAutoMapping> createAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
final String mapKey = resultMap.getId() + ":" + columnPrefix;
List<UnMappedColumAutoMapping> autoMapping = autoMappingsCache.get(mapKey);
if (autoMapping == null) {
autoMapping = new ArrayList<UnMappedColumAutoMapping>();
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
for (String columnName : unmappedColumnNames) {
String propertyName = columnName;
if (columnPrefix != null && !columnPrefix.isEmpty()) {
if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
propertyName = columnName.substring(columnPrefix.length());
} else {
continue;
}
}
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
if (property != null && metaObject.hasSetter(property)) {
final Class<?> propertyType = metaObject.getSetterType(property);
if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
autoMapping.add(new UnMappedColumAutoMapping(columnName, property, typeHandler, propertyType.isPrimitive()));
}
}
}
autoMappingsCache.put(mapKey, autoMapping);
}
return autoMapping;
}
在下面的源碼中createAutomaticMappings()辦法中的上面這句就是獲取以後查詢後果集中沒有在resultMap中映射的字段,以停止自動映射。概況請參考完好的源碼。
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
1.2 示例
現假定我們有一個User類,其有id、name、username、email、mobile屬性,然後有上面這樣一個查詢及其對應的resultMap定義。我們可以看到我們查詢出來的有id、name、user_name、email和mobile字段,在resultMap中我們只配置了字段user_name對應的是username屬性,其它的我們都沒配置,但是查詢出來的後果中User對象的id、name、username、email和mobile屬性都會有值,由於它們會被Mybatis以自動映射戰略停止賦值。
<resultMap type="com.elim.learn.mybatis.model.User" id="BaseResult">
<result column="user_name" property="username"/>
</resultMap>
<select id="findById" resultMap="BaseResult" parameterType="java.lang.Long" >
select id,name,username user_name,email,mobile from t_user where id=#{id}
</select>
1.3 自動映射戰略
Mybatis的自動映射戰略默許是開啟的,而且默許是只對非嵌套的resultMap停止自動映射。這是經過Mybatis的全局配置autoMappingBehavior參數配置的。它一共有三種取值,辨別是NONE、PARTIAL和FULL。
l NONE表示不啟用自動映射
l PARTIAL表示只對非嵌套的resultMap停止自動映射
l FULL表示對一切的resultMap都停止自動映射
<!-- 自動映射類型,可選值為NONE、PARTIAL和FULL,參考AutoMappingBehavior枚舉 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
除了全局的能否啟用自動映射的配置外,還可以對特定的resultMap設置能否啟用自動映射。這是經過resultMap的autoMapping屬性配置的,可選值是true和false。定義在resultMap上的autoMapping的優先級比全局配置的優先級更高。
1.4 resultType自動映射剖析
我們在指定一個查詢語句的前往後果時,可以直接指定resultType,也可以是指定resultMap,然後由指定的resultMap的type屬性指定真實的前往類型。實踐上,Mybatis的底層在對後果集停止處置時都是經過resultMap停止處置的。當我們指定的是resultType時,Mybatis外部會生成一個空的resultMap,然後指定其對應的type為我們指定的resultType類型。那這個時分之所以前往後果能自動映射到resultType類型的對應屬性上,就是下面引見的Mybatis的自動映射機制的作用。假如在這種狀況下,我們把全局的自動映射封閉了,那麼Mybatis就不能自動映射了,也就得不到我們需求的前往後果了。如下就是直接指定的resultType。
<select id="findById" resultType="com.elim.learn.mybatis.model.User" parameterType="java.lang.Long" >
select id,name,username,email,mobile from t_user where id=#{id}
</select>
Mybatis的mapper.xml文件的內容是由XMLMapperBuilder解析的,而其中定義的Mapper語句(select、insert等)則是由XMLStatementBuilder解析的,解析後會生成一個MappedStatement。關於Select語句,其對應的resultMap的解析的中心邏輯如下,更多信息請參考官方源碼。
private List<ResultMap> getStatementResultMaps(
String resultMap,
Class<?> resultType,
String statementId) {
resultMap = applyCurrentNamespace(resultMap, true);
List<ResultMap> resultMaps = new ArrayList<ResultMap>();
if (resultMap != null) {
String[] resultMapNames = resultMap.split(",");
for (String resultMapName : resultMapNames) {
try {
resultMaps.add(configuration.getResultMap(resultMapName.trim()));
} catch (IllegalArgumentException e) {
throw new IncompleteElementException("Could not find result map " + resultMapName, e);
}
}
} else if (resultType != null) {
ResultMap inlineResultMap = new ResultMap.Builder(
configuration,
statementId + "-Inline",
resultType,
new ArrayList<ResultMapping>(),
null).build();
resultMaps.add(inlineResultMap);
}
return resultMaps;
}
以上所述是給大家引見的Mybatis後果集自動映射的實例代碼,希望對大家有所協助,假如大家有任何疑問請給我留言,會及時回復大家的。在此也十分感激大家對網站的支持!