📄 basicresultmap.java
字号:
}
columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, javaType);
} else if (DomTypeMarker.class.isAssignableFrom(resultClass)) {
Class javaType = mapping.getJavaType();
if (javaType == null) {
javaType = DomTypeMarker.class;
}
columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, javaType);
} else {
Probe p = ProbeFactory.getProbe(resultClass);
Class type = p.getPropertyTypeForSetter(resultClass, mapping.getPropertyName());
columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, type);
}
foundData = foundData || columnValues[i] != null;
} else if (mapping.getNestedResultMapName() == null) {
columnValues[i] = getPrimitiveResultMappingValue(rs, mapping);
if (columnValues[i] == null) {
columnValues[i] = doNullMapping(columnValues[i], mapping);
}
else {
foundData = true;
}
}
}
request.setRowDataFound(foundData);
return columnValues;
}
public Object setResultObjectValues(RequestScope request, Object resultObject, Object[] values) {
String ukey = (String)getUniqueKey(request.getCurrentNestedKey(), values);
Map uniqueKeys = request.getUniqueKeys(this);
request.setCurrentNestedKey(ukey);
if (uniqueKeys != null && uniqueKeys.containsKey(ukey)) {
// Unique key is already known, so get the existing result object and process additional results.
resultObject = uniqueKeys.get(ukey);
applyNestedResultMap(request, resultObject, values);
resultObject = NO_VALUE;
} else if (ukey == null || uniqueKeys == null || !uniqueKeys.containsKey(ukey)) {
// Unique key is NOT known, so create a new result object and then process additional results.
resultObject = dataExchange.setData(request, this, resultObject, values);
// Lazy init key set, only if we're grouped by something (i.e. ukey != null)
if (ukey != null) {
if (uniqueKeys == null) {
uniqueKeys = new HashMap();
request.setUniqueKeys(this, uniqueKeys);
}
uniqueKeys.put(ukey, resultObject);
}
applyNestedResultMap(request, resultObject, values);
} else {
// Otherwise, we don't care about these results.
resultObject = NO_VALUE;
}
return resultObject;
}
private void applyNestedResultMap(RequestScope request, Object resultObject, Object[] values) {
if (resultObject != null && resultObject != NO_VALUE) {
if (nestedResultMappings != null) {
for (int i = 0, n = nestedResultMappings.size(); i < n; i++) {
BasicResultMapping resultMapping = (BasicResultMapping) nestedResultMappings.get(i);
setNestedResultMappingValue(resultMapping, request, resultObject, values);
}
}
}
}
/**
* Some changes in this method for IBATIS-225:
* <ul>
* <li>We no longer require the nested property to be a collection. This
* will allow reuses of resultMaps on 1:1 relationships</li>
* <li>If the nested property is not a collection, then it will be
* created/replaced by the values generated from the current row.</li>
* </ul>
*
* @param mapping
* @param request
* @param resultObject
* @param values
*/
protected void setNestedResultMappingValue(BasicResultMapping mapping, RequestScope request, Object resultObject, Object[] values) {
try {
String resultMapName = mapping.getNestedResultMapName();
ResultMap resultMap = getDelegate().getResultMap(resultMapName);
// get the discriminated submap if it exists
resultMap = resultMap.resolveSubMap(request, request.getResultSet());
Class type = mapping.getJavaType();
String propertyName = mapping.getPropertyName();
Object obj = PROBE.getObject(resultObject, propertyName);
if (obj == null) {
if (type == null) {
type = PROBE.getPropertyTypeForSetter(resultObject, propertyName);
}
try {
// create the object if is it a Collection. If not a Collection
// then we will just set the property to the object created
// in processing the nested result map
if (Collection.class.isAssignableFrom(type)) {
obj = ResultObjectFactoryUtil.createObjectThroughFactory(type);
PROBE.setObject(resultObject, propertyName, obj);
}
} catch (Exception e) {
throw new SqlMapException("Error instantiating collection property for mapping '" + mapping.getPropertyName() + "'. Cause: " + e, e);
}
}
values = resultMap.getResults(request, request.getResultSet());
if (request.isRowDataFound()) {
Object o = resultMap.setResultObjectValues(request, null, values);
if (o != NO_VALUE) {
if (obj != null && obj instanceof Collection) {
((Collection) obj).add(o);
} else {
PROBE.setObject(resultObject, propertyName, o);
}
}
}
} catch (SQLException e) {
throw new SqlMapException("Error getting nested result map values for '" + mapping.getPropertyName() + "'. Cause: " + e, e);
}
}
protected Object getNestedSelectMappingValue(RequestScope request, ResultSet rs, BasicResultMapping mapping, Class targetType)
throws SQLException {
try {
TypeHandlerFactory typeHandlerFactory = getDelegate().getTypeHandlerFactory();
String statementName = mapping.getStatementName();
ExtendedSqlMapClient client = (ExtendedSqlMapClient) request.getSession().getSqlMapClient();
MappedStatement mappedStatement = client.getMappedStatement(statementName);
Class parameterType = mappedStatement.getParameterClass();
Object parameterObject = null;
if (parameterType == null) {
parameterObject = prepareBeanParameterObject(request, rs, mapping, parameterType);
} else {
if (typeHandlerFactory.hasTypeHandler(parameterType)) {
parameterObject = preparePrimitiveParameterObject(rs, mapping, parameterType);
} else if (DomTypeMarker.class.isAssignableFrom(parameterType)) {
parameterObject = prepareDomParameterObject(rs, mapping);
} else {
parameterObject = prepareBeanParameterObject(request, rs, mapping, parameterType);
}
}
Object result = null;
if (parameterObject != null) {
Sql sql = mappedStatement.getSql();
ResultMap resultMap = sql.getResultMap(request, parameterObject);
Class resultClass = resultMap.getResultClass();
if (resultClass != null && !DomTypeMarker.class.isAssignableFrom(targetType)) {
if (DomCollectionTypeMarker.class.isAssignableFrom(resultClass)) {
targetType = DomCollectionTypeMarker.class;
} else if (DomTypeMarker.class.isAssignableFrom(resultClass)) {
targetType = DomTypeMarker.class;
}
}
result = ResultLoader.loadResult(client, statementName, parameterObject, targetType);
String nullValue = mapping.getNullValue();
if (result == null && nullValue != null) {
TypeHandler typeHandler = typeHandlerFactory.getTypeHandler(targetType);
if (typeHandler != null) {
result = typeHandler.valueOf(nullValue);
}
}
}
return result;
} catch (InstantiationException e) {
throw new NestedSQLException("Error setting nested bean property. Cause: " + e, e);
} catch (IllegalAccessException e) {
throw new NestedSQLException("Error setting nested bean property. Cause: " + e, e);
}
}
private Object preparePrimitiveParameterObject(ResultSet rs, BasicResultMapping mapping, Class parameterType) throws SQLException {
Object parameterObject;
TypeHandlerFactory typeHandlerFactory = getDelegate().getTypeHandlerFactory();
TypeHandler th = typeHandlerFactory.getTypeHandler(parameterType);
parameterObject = th.getResult(rs, mapping.getColumnName());
return parameterObject;
}
private Document newDocument(String root) {
try {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
doc.appendChild(doc.createElement(root));
return doc;
} catch (ParserConfigurationException e) {
throw new RuntimeException("Error creating XML document. Cause: " + e);
}
}
private Object prepareDomParameterObject(ResultSet rs, BasicResultMapping mapping) throws SQLException {
TypeHandlerFactory typeHandlerFactory = getDelegate().getTypeHandlerFactory();
Document doc = newDocument("parameter");
Probe probe = ProbeFactory.getProbe(doc);
String complexName = mapping.getColumnName();
TypeHandler stringTypeHandler = typeHandlerFactory.getTypeHandler(String.class);
if (complexName.indexOf('=') > -1) {
// old 1.x style multiple params
StringTokenizer parser = new StringTokenizer(complexName, "{}=, ", false);
while (parser.hasMoreTokens()) {
String propName = parser.nextToken();
String colName = parser.nextToken();
Object propValue = stringTypeHandler.getResult(rs, colName);
probe.setObject(doc, propName, propValue.toString());
}
} else {
// single param
Object propValue = stringTypeHandler.getResult(rs, complexName);
probe.setObject(doc, "value", propValue.toString());
}
return doc;
}
private Object prepareBeanParameterObject(RequestScope request, ResultSet rs, BasicResultMapping mapping, Class parameterType)
throws InstantiationException, IllegalAccessException, SQLException {
TypeHandlerFactory typeHandlerFactory = getDelegate().getTypeHandlerFactory();
Object parameterObject;
if (parameterType == null) {
parameterObject = new HashMap();
} else {
parameterObject = ResultObjectFactoryUtil.createObjectThroughFactory(parameterType);
}
String complexName = mapping.getColumnName();
if (complexName.indexOf('=') > -1
|| complexName.indexOf(',') > -1) {
StringTokenizer parser = new StringTokenizer(complexName, "{}=, ", false);
while (parser.hasMoreTokens()) {
String propName = parser.nextToken();
String colName = parser.nextToken();
Class propType = PROBE.getPropertyTypeForSetter(parameterObject, propName);
TypeHandler propTypeHandler = typeHandlerFactory.getTypeHandler(propType);
Object propValue = propTypeHandler.getResult(rs, colName);
PROBE.setObject(parameterObject, propName, propValue);
}
} else {
// single param
TypeHandler propTypeHandler = typeHandlerFactory.getTypeHandler(parameterType);
if (propTypeHandler == null) {
propTypeHandler = typeHandlerFactory.getUnkownTypeHandler();
}
parameterObject = propTypeHandler.getResult(rs, complexName);
}
return parameterObject;
}
protected Object getPrimitiveResultMappingValue(ResultSet rs, BasicResultMapping mapping) throws SQLException {
Object value = null;
TypeHandler typeHandler = mapping.getTypeHandler();
//FIXME by wangwp
//这里增加iBatis配置文件中的映射字段的合法性判断,判断数据库查询结果ResultSet中是否包含ResultMap中对应的column
//如果不存在的话,对应的属性值直接返回null,而不是出现异常
ResultSetMetaData metadata = rs.getMetaData();
int columnCount = metadata.getColumnCount();
Map<Integer, String> columnMap = new HashMap<Integer, String>();
for(int i=1; i<=columnCount; i++){
columnMap.put(i, metadata.getColumnLabel(i));
}
if (typeHandler != null) {
String columnName = mapping.getColumnName();
int columnIndex = mapping.getColumnIndex();
//FIXME 在下面增加判断
if (columnName == null) {
if(!columnMap.containsKey(columnIndex)){
value = null;
}else{
value = typeHandler.getResult(rs, columnIndex);
}
} else {
if(!columnMap.containsValue(columnName)){
value = null;
}else{
value = typeHandler.getResult(rs, columnName);
}
}
} else {
throw new SqlMapException("No type handler could be found to map the property '" + mapping.getPropertyName() + "' to the column '" + mapping.getColumnName() + "'. One or both of the types, or the combination of types is not supported.");
}
return value;
}
protected Object doNullMapping(Object value, BasicResultMapping mapping) throws SqlMapException {
if ( value == null ) {
TypeHandler typeHandler = mapping.getTypeHandler();
if (typeHandler != null) {
String nullValue = mapping.getNullValue();
if ( nullValue != null )
value = typeHandler.valueOf(nullValue);
return value;
} else {
throw new SqlMapException("No type handler could be found to map the property '" + mapping.getPropertyName() + "' to the column '" + mapping.getColumnName() + "'. One or both of the types, or the combination of types is not supported.");
}
}
else {
return value;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -