Author: cbegin
Date: Tue Sep 8 04:10:33 2009
New Revision: 812337
URL: http://svn.apache.org/viewvc?rev=812337&view=rev
Log:
included composite columns in mapped column set.
added some nested result map functionality
Modified:
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/NewResultSetHandler.java
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMap.java
Modified:
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/NewResultSetHandler.java
URL:
http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/NewResultSetHandler.java?rev=812337&r1=812336&r2=812337&view=diff
==============================================================================
---
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/NewResultSetHandler.java
(original)
+++
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/NewResultSetHandler.java
Tue Sep 8 04:10:33 2009
@@ -7,6 +7,7 @@
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.executor.Executor;
+import static org.apache.ibatis.executor.resultset.NoValue.NO_VALUE;
import org.apache.ibatis.executor.loader.ResultLoader;
import org.apache.ibatis.executor.loader.ResultLoaderRegistry;
import org.apache.ibatis.executor.loader.ResultObjectProxy;
@@ -16,10 +17,7 @@
import org.apache.ibatis.executor.result.DefaultResultContext;
import org.apache.ibatis.cache.CacheKey;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.HashMap;
+import java.util.*;
import java.sql.*;
public class NewResultSetHandler implements ResultSetHandler {
@@ -123,8 +121,9 @@
final Object resultObject = createResultObject(rs,
discriminatedResultMap, lazyLoader);
final MetaObject metaObject = MetaObject.forObject(resultObject);
getMappedAndUnmappedColumnNames(rs, discriminatedResultMap,
mappedColumnNames, unmappedColumnNames);
- applyPropertyMappings(rs, discriminatedResultMap , mappedColumnNames,
metaObject, lazyLoader);
+ applyPropertyMappings(rs, discriminatedResultMap, mappedColumnNames,
metaObject, lazyLoader);
applyAutomaticMappings(rs, unmappedColumnNames, metaObject);
+ processNestedJoinResults(rs, resultMap, resultObject);
resultContext.nextResultObject(resultObject);
resultHandler.handleResult(resultContext);
}
@@ -146,7 +145,7 @@
if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
rs.absolute(rowLimit.getOffset());
} else {
- for (int i=0; i < rowLimit.getOffset(); i++) rs.next();
+ for (int i = 0; i < rowLimit.getOffset(); i++) rs.next();
}
}
@@ -173,7 +172,7 @@
final List<ResultMapping> propertyMappings =
resultMap.getPropertyResultMappings();
for (ResultMapping propertyMapping : propertyMappings) {
final String column = propertyMapping.getColumn();
- if (column != null && mappedColumnNames.contains(column.toUpperCase())) {
+ if (propertyMapping.isCompositeResult() || (column != null &&
mappedColumnNames.contains(column.toUpperCase()))) {
final TypeHandler typeHandler = propertyMapping.getTypeHandler();
if (propertyMapping.getNestedQueryId() != null) {
applyNestedQueryMapping(rs, metaObject, resultMap, propertyMapping,
lazyLoader);
@@ -221,7 +220,7 @@
}
private void applyAutomaticMappings(ResultSet rs, List<String>
unmappedColumnNames, MetaObject metaObject) throws SQLException {
- for(String columnName : unmappedColumnNames) {
+ for (String columnName : unmappedColumnNames) {
final String property = metaObject.findProperty(columnName);
if (property != null) {
final Class propertyType = metaObject.getSetterType(property);
@@ -240,7 +239,7 @@
final ResultSetMetaData rsmd = rs.getMetaData();
final int columnCount = rsmd.getColumnCount();
final Set<String> mappedColumns = resultMap.getMappedColumns();
- for(int i=1; i<=columnCount; i++) {
+ for (int i = 1; i <= columnCount; i++) {
final String columnName = configuration.isUseColumnLabel() ?
rsmd.getColumnLabel(i) : rsmd.getColumnName(i);
final String upperColumnName = columnName.toUpperCase();
if (mappedColumns.contains(upperColumnName)) {
@@ -278,7 +277,7 @@
private Object createParameterizedResultObject(ResultSet rs, Class
resultType, List<ResultMapping> constructorMappings) throws SQLException {
final List<Class> parameterTypes = new ArrayList<Class>();
final List<Object> parameterValues = new ArrayList<Object>();
- for(ResultMapping constructorMapping : constructorMappings) {
+ for (ResultMapping constructorMapping : constructorMappings) {
final Class parameterType = constructorMapping.getJavaType();
final TypeHandler typeHandler = constructorMapping.getTypeHandler();
final String column = constructorMapping.getColumn();
@@ -293,7 +292,7 @@
final ResultSetMetaData rsmd = rs.getMetaData();
final String columnName = configuration.isUseColumnLabel() ?
rsmd.getColumnLabel(1) : rsmd.getColumnName(1);
final TypeHandler typeHandler =
typeHandlerRegistry.getTypeHandler(resultType);
- return typeHandler.getResult(rs,columnName);
+ return typeHandler.getResult(rs, columnName);
}
//
@@ -342,7 +341,7 @@
// DISCRIMINATOR
//
- public ResultMap resolveDiscriminatedResultMap(ResultSet rs, ResultMap
resultMap) throws SQLException {
+ public ResultMap resolveDiscriminatedResultMap(ResultSet rs, ResultMap
resultMap) throws SQLException {
final Discriminator discriminator = resultMap.getDiscriminator();
if (discriminator != null) {
final Object value = getDiscriminatorValue(rs, discriminator);
@@ -364,4 +363,133 @@
}
}
+ //
+ // NESTED RESULT MAP (JOIN MAPPING)
+ //
+
+ private Map nestedResultObjects = new HashMap();
+ private CacheKey currentNestedKey;
+
+ private Object processNestedJoinResults(ResultSet rs, ResultMap resultMap,
Object resultObject) {
+ CacheKey previousKey = currentNestedKey;
+ try {
+ currentNestedKey = createUniqueResultKey(resultMap, resultObject);
+ if (nestedResultObjects.containsKey(currentNestedKey)) {
+ // Unique key is already known, so get the existing result object and
process additional results.
+ resultObject = NO_VALUE;
+ } else if (currentNestedKey != null) {
+ // Unique key is NOT known, so create a new result object and then
process additional results.
+ nestedResultObjects.put(currentNestedKey, resultObject);
+ }
+ Object knownResultObject = nestedResultObjects.get(currentNestedKey);
+ if (knownResultObject != null && resultObject != NO_VALUE) {
+ applyNestedResultMappings(rs, resultMap, knownResultObject);
+ }
+ return resultObject;
+
+ } finally {
+ currentNestedKey = previousKey;
+ }
+ }
+
+ private void applyNestedResultMappings(ResultSet rs, ResultMap resultMap,
Object resultObject) {
+ for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) {
+ final String nestedResultMapId = resultMapping.getNestedResultMapId();
+ if (nestedResultMapId != null) {
+ try {
+ final ResultMap nestedResultMap = getNestedResultMap(rs,
nestedResultMapId);
+ final MetaObject metaObject = MetaObject.forObject(resultObject);
+ final Object propertyValue = getPropertyValue(resultMapping,
metaObject);
+ final Reference<Boolean> foundValues = new Reference(false);
+
+ final DefaultResultHandler defaultResultHandler = new
DefaultResultHandler();
+ handleResultSet(rs, nestedResultMap, defaultResultHandler, new
RowLimit());
+ final List nestedResults = defaultResultHandler.getResultList();
+
+ if (propertyValue != null && propertyValue instanceof Collection) {
+ if (foundValues.get()) {
+ ((Collection) propertyValue).addAll(nestedResults);
+ }
+ } else {
+ if (nestedResults.size() == 1) {
+ final Object nestedResultObject = nestedResults.get(0);
+ metaObject.setValue(resultMapping.getProperty(),
nestedResultObject);
+ } else {
+ throw new ExecutorException("Expected exactly 1 or 0 results for
'" + resultMapping.getProperty() + "', but found "+nestedResults.size()+".");
+ }
+ }
+
+ } catch (Exception e) {
+ throw new ExecutorException("Error getting nested result map values
for '" + resultMapping.getProperty() + "'. Cause: " + e, e);
+ }
+ }
+ }
+ }
+
+ private Object getPropertyValue(ResultMapping resultMapping, MetaObject
metaObject) {
+ final String propertyName = resultMapping.getProperty();
+ Class type = resultMapping.getJavaType();
+ Object propertyValue = metaObject.getValue(propertyName);
+ if (propertyValue == null) {
+ if (type == null) {
+ type = metaObject.getSetterType(propertyName);
+ }
+ try {
+ if (Collection.class.isAssignableFrom(type)) {
+ propertyValue = objectFactory.create(type);
+ metaObject.setValue(propertyName, propertyValue);
+ }
+ } catch (Exception e) {
+ throw new ExecutorException("Error instantiating collection property
for result '" + resultMapping.getProperty() + "'. Cause: " + e, e);
+ }
+ }
+ return propertyValue;
+ }
+
+ private ResultMap getNestedResultMap(ResultSet rs, String nestedResultMapId)
throws SQLException {
+ ResultMap nestedResultMap = configuration.getResultMap(nestedResultMapId);
+ nestedResultMap = resolveDiscriminatedResultMap(rs, nestedResultMap);
+ return nestedResultMap;
+ }
+
+ //
+ // UNIQUE RESULT KEY
+ //
+
+ private CacheKey createUniqueResultKey(ResultMap resultMap, Object
resultObject) {
+ if (resultObject == null) {
+ return null;
+ } else {
+ return createCacheKeyForResultObject(resultMap, resultObject);
+ }
+ }
+
+ private CacheKey createCacheKeyForResultObject(ResultMap resultMap, Object
resultObject) {
+ final CacheKey cacheKey = new CacheKey();
+ cacheKey.update(resultMap.getType().getName());
+ if (typeHandlerRegistry.hasTypeHandler(resultObject.getClass())) {
+ cacheKey.update(resultObject);
+ } else {
+ updateCacheKeyForComplexResultObject(resultMap, resultObject, cacheKey);
+ }
+ return cacheKey;
+ }
+
+ private void updateCacheKeyForComplexResultObject(ResultMap resultMap,
Object resultObject, CacheKey cacheKey) {
+ final MetaObject metaResultObject = MetaObject.forObject(resultObject);
+ for (ResultMapping resultMapping : resultMap.getIdResultMappings()) {
+ if (resultMapping.getNestedQueryId() == null &&
resultMapping.getNestedResultMapId() == null) {
+ final String propName = resultMapping.getProperty();
+ if (propName != null) {
+ final Object value = metaResultObject.getValue(propName);
+ if (value != null) {
+ cacheKey.update(propName);
+ cacheKey.update(value);
+ }
+ }
+ }
+ }
+ }
+
+
}
Modified:
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMap.java
URL:
http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMap.java?rev=812337&r1=812336&r2=812337&view=diff
==============================================================================
---
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMap.java
(original)
+++
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/ResultMap.java
Tue Sep 8 04:10:33 2009
@@ -43,6 +43,13 @@
final String column = resultMapping.getColumn();
if (column != null) {
resultMap.mappedColumns.add(column.toUpperCase());
+ } else if (resultMapping.isCompositeResult()) {
+ for (ResultMapping compositeResultMapping :
resultMapping.getComposites()) {
+ final String compositeColumn = compositeResultMapping.getColumn();
+ if (compositeColumn != null) {
+ resultMap.mappedColumns.add(compositeColumn.toUpperCase());
+ }
+ }
}
if (resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR)) {
resultMap.constructorResultMappings.add(resultMapping);