private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) { try { if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) { String keyProperty = keyStatement.getKeyProperties()[0]; // just one key property is supported final Configuration configuration = ms.getConfiguration(); final MetaObject metaParam = configuration.newMetaObject(parameter); if (keyProperty != null && metaParam.hasSetter(keyProperty)) { // Do not close keyExecutor. // The transaction will be closed by parent executor. Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE); List<Object> values = keyExecutor.query( keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER); if (values.size() == 0) { throw new ExecutorException("SelectKey returned no data."); } else if (values.size() > 1) { throw new ExecutorException("SelectKey returned more than one value."); } else { metaParam.setValue(keyProperty, values.get(0)); } } } } catch (ExecutorException e) { throw e; } catch (Exception e) { throw new ExecutorException( "Error selecting key or setting result to parameter object. Cause: " + e, e); } }
private void pagination(Invocation invocation, StatementHandler target) throws SQLException { final MetaObject metaStatementHandler = getMetaObject(target); final BoundSql boundSql = target.getBoundSql(); Page<?> page = PAGE_THREAD_LOCAL.get(); if (page == null) { page = findPageParameter(boundSql.getParameterObject()); } // 如果传入的参数中有分页对象且sql语句中有select,才做分页处理 String sql = boundSql.getSql().toLowerCase(); if (sql.startsWith("select") && page != null) { // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数 metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET); metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT); // 设置分页对象里的总记录数和总页数 Connection connection = (Connection) invocation.getArgs()[0]; MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); if (page.isCountTotal()) { int recordsTotal = getTotalCount(sql, connection, mappedStatement, boundSql); page.setTotalNum(recordsTotal); } // 最后重写sql String pageSql = buildPageSql(sql, page); metaStatementHandler.setValue("delegate.boundSql.sql", pageSql); } }
@Test public void shouldGetAndSetNestedProperty() { RichType rich = new RichType(); MetaObject meta = SystemMetaObject.forObject(rich); meta.setValue("richType.richProperty", "foo"); assertEquals("foo", meta.getValue("richType.richProperty")); }
@Test public void shouldGetAndSetMapPair() { RichType rich = new RichType(); MetaObject meta = SystemMetaObject.forObject(rich); meta.setValue("richMap.key", "foo"); assertEquals("foo", meta.getValue("richMap.key")); }
@Test public void shouldGetAndSetNestedMapPairUsingArraySyntax() { RichType rich = new RichType(); MetaObject meta = SystemMetaObject.forObject(rich); meta.setValue("richType.richMap[key]", "foo"); assertEquals("foo", meta.getValue("richType.richMap[key]")); }
/** * 获取查询sql <功能详细描述> * * @return [参数说明] * @return String [返回类型说明] * @exception throws [异常类型] [异常说明] * @see [类、类#方法、类#成员] */ public String countSql(Object obj) { // 构建query语句 SqlBuilder.BEGIN(); SqlBuilder.SELECT("COUNT(1)"); SqlBuilder.FROM(this.tableName); if (!ObjectUtils.isEmpty(obj)) { MetaObject metaObject = MetaObjectUtils.forObject(obj); for (Entry<String, String> entryTemp : queryConditionKey2SqlMapping.entrySet()) { String queryKeyName = entryTemp.getKey(); Object valueObj = metaObject.getValue(queryKeyName); if (ObjectUtils.isEmpty(valueObj)) { continue; } SqlBuilder.WHERE(entryTemp.getValue()); } } for (String conditionExpressionTemp : otherCondition) { SqlBuilder.WHERE(conditionExpressionTemp); } String querySql = SqlBuilder.SQL(); SqlBuilder.RESET(); return querySql; }
/** * 获取查询sql <功能详细描述> * * @return [参数说明] * @return String [返回类型说明] * @exception throws [异常类型] [异常说明] * @see [类、类#方法、类#成员] */ public String updateSql(Object obj) { AssertUtils.notEmpty(obj, "update obj must not empty."); // 获取当前对象中有哪些属性 MetaObject metaObject = MetaObjectUtils.forObject(obj); Set<String> keySet = new HashSet<String>(); for (String getterName : metaObject.getGetterNames()) { keySet.add(getterName); } AssertUtils.isTrue( keySet.contains(this.pkName), "obj:{} must contains pk{}.", new Object[] {obj, this.pkName}); // 构建query语句 SqlBuilder.BEGIN(); SqlBuilder.UPDATE(this.tableName); for (String propertyName : updateAblePropertyNames) { if (!keySet.contains(propertyName)) { continue; } // Object value = metaObject.getValue(propertyName); String columnName = getter2columnNameMapping.get(propertyName); SqlBuilder.SET(columnName + " = ?"); } SqlBuilder.WHERE(this.getter2columnNameMapping.get(this.pkName) + " = ? "); String updateSql = SqlBuilder.SQL(); SqlBuilder.RESET(); return updateSql; }
@Test public void shouldVerifyHasWriteablePropertiesReturnedByGetWriteablePropertyNames() { MetaObject object = SystemMetaObject.forObject(new Author()); for (String writeable : object.getSetterNames()) { assertTrue(object.hasSetter(writeable)); } }
@Test public void shouldSetAndGetSelfListItem() { RichType rich = new RichType(); MetaObject meta = SystemMetaObject.forObject(rich); meta.setValue("richList[0]", "foo"); assertEquals("foo", meta.getValue("richList[0]")); }
/** * 获取查询条件的Setter对象 <功能详细描述> * * @param obj * @return [参数说明] * @return PreparedStatementSetter [返回类型说明] * @exception throws [异常类型] [异常说明] * @see [类、类#方法、类#成员] */ public PreparedStatementSetter getUpdateSetter(Object obj) { AssertUtils.notEmpty(obj, "update obj must not empty."); // 获取当前对象中有哪些属性 final MetaObject metaObject = MetaObjectUtils.forObject(obj); final Set<String> keySet = new HashSet<String>(); for (String getterName : metaObject.getGetterNames()) { keySet.add(getterName); } AssertUtils.isTrue( keySet.contains(this.pkName), "obj:{} must contains pk{}.", new Object[] {obj, this.pkName}); final String finalPkName = this.pkName; PreparedStatementSetter res = new PreparedStatementSetter() { @Override public void setValues(PreparedStatement ps) throws SQLException { int i = 1; for (String propertyNameTemp : updateAblePropertyNames) { if (!keySet.contains(propertyNameTemp)) { continue; } Object valueObj = metaObject.getValue(propertyNameTemp); Class<?> setterType = getter2JavaTypeMapping.get(propertyNameTemp); JdbcUtils.setPreparedStatementValueForSimpleType(ps, i++, valueObj, setterType); } Class<?> setterType = getter2JavaTypeMapping.get(finalPkName); JdbcUtils.setPreparedStatementValueForSimpleType( ps, i, metaObject.getValue(finalPkName), setterType); } }; return res; }
public PageDynamicSqlSource(DynamicSqlSource sqlSource, Parser parser) { MetaObject metaObject = SystemMetaObject.forObject(sqlSource); this.configuration = (Configuration) metaObject.getValue("configuration"); this.rootSqlNode = (SqlNode) metaObject.getValue("rootSqlNode"); this.original = sqlSource; this.parser = parser; }
private SqlSource getSqlSource( MappedStatement ms, SqlSource sqlSource, Object parameterObject, boolean isCount) { if (ms.getSqlSource() instanceof DynamicSqlSource) { MetaObject msObject = MetaObjectUtils.forObject(ms); SqlNode sqlNode = (SqlNode) msObject.getValue("sqlSource.rootSqlNode"); MixedSqlNode mixedSqlNode = null; if (sqlNode instanceof MixedSqlNode) { mixedSqlNode = (MixedSqlNode) sqlNode; } else { List<SqlNode> contents = new ArrayList<SqlNode>(1); contents.add(sqlNode); mixedSqlNode = new MixedSqlNode(contents); } return new CustomerDynamicSqlSource(ms.getConfiguration(), mixedSqlNode, isCount, dialect); } else if (sqlSource instanceof ProviderSqlSource) { return new CustomerProviderSqlSource( ms.getConfiguration(), (ProviderSqlSource) sqlSource, isCount, dialect); } else if (!isCount) { BoundSql boundSql = sqlSource.getBoundSql(parameterObject); return new StaticSqlSource( ms.getConfiguration(), dialect.generatePageSQL(boundSql.getSql()), MybatisUtils.plusTwoParameterToMapping(ms.getConfiguration(), boundSql)); } else { BoundSql boundSql = sqlSource.getBoundSql(parameterObject); return new StaticSqlSource( ms.getConfiguration(), dialect.generateCountSQL(boundSql.getSql()), boundSql.getParameterMappings()); } }
private Object instantiateCollectionPropertyIfAppropriate( ResultMapping resultMapping, MetaObject metaObject) { final String propertyName = resultMapping.getProperty(); Object propertyValue = metaObject.getValue(propertyName); if (propertyValue == null) { Class<?> type = resultMapping.getJavaType(); if (type == null) { type = metaObject.getSetterType(propertyName); } try { if (objectFactory.isCollection(type)) { propertyValue = objectFactory.create(type); metaObject.setValue(propertyName, propertyValue); return propertyValue; } } catch (Exception e) { throw new ExecutorException( "Error instantiating collection property for result '" + resultMapping.getProperty() + "'. Cause: " + e, e); } } else if (objectFactory.isCollection(propertyValue.getClass())) { return propertyValue; } return null; }
private boolean applyAutomaticMappings( ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException { final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix); boolean foundValues = false; for (String columnName : unmappedColumnNames) { String propertyName = columnName; if (columnPrefix != null && columnPrefix.length() > 0) { // When columnPrefix is specified, // ignore columns without the prefix. 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); final Object value = typeHandler.getResult(rsw.getResultSet(), columnName); if (value != null || configuration.isCallSettersOnNulls()) { // issue #377, call setter on nulls if (value != null || !propertyType.isPrimitive()) { metaObject.setValue(property, value); } foundValues = true; } } } } return foundValues; }
private boolean applyPropertyMappings( ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException { final List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix); boolean foundValues = false; final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings(); for (ResultMapping propertyMapping : propertyMappings) { final String column = prependPrefix(propertyMapping.getColumn(), columnPrefix); if (propertyMapping.isCompositeResult() || (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH))) || propertyMapping.getResultSet() != null) { Object value = getPropertyMappingValue( rsw.getResultSet(), metaObject, propertyMapping, lazyLoader, columnPrefix); final String property = propertyMapping.getProperty(); // issue #541 make property optional if (value != NO_VALUE && property != null && (value != null || configuration.isCallSettersOnNulls())) { // issue #377, call setter on nulls if (value != null || !metaObject.getSetterType(property).isPrimitive()) { metaObject.setValue(property, value); } foundValues = true; } } } return foundValues; }
public CacheKey createCacheKey( MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) { if (closed) throw new ExecutorException("Executor was closed."); CacheKey cacheKey = new CacheKey(); cacheKey.update(ms.getId()); cacheKey.update(rowBounds.getOffset()); cacheKey.update(rowBounds.getLimit()); cacheKey.update(boundSql.getSql()); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); if (parameterMappings.size() > 0 && parameterObject != null) { TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry(); if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { cacheKey.update(parameterObject); } else { MetaObject metaObject = configuration.newMetaObject(parameterObject); for (ParameterMapping parameterMapping : parameterMappings) { String propertyName = parameterMapping.getProperty(); if (metaObject.hasGetter(propertyName)) { cacheKey.update(metaObject.getValue(propertyName)); } else if (boundSql.hasAdditionalParameter(propertyName)) { cacheKey.update(boundSql.getAdditionalParameter(propertyName)); } } } } return cacheKey; }
public PageStaticSqlSource(StaticSqlSource sqlSource, Parser parser) { MetaObject metaObject = SystemMetaObject.forObject(sqlSource); this.sql = (String) metaObject.getValue("sql"); this.parameterMappings = (List<ParameterMapping>) metaObject.getValue("parameterMappings"); this.configuration = (Configuration) metaObject.getValue("configuration"); this.original = sqlSource; this.parser = parser; }
private boolean applyNestedResultMappings( ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String parentPrefix, CacheKey parentRowKey, boolean newObject) { boolean foundValues = false; for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) { final String nestedResultMapId = resultMapping.getNestedResultMapId(); if (nestedResultMapId != null && resultMapping.getResultSet() == null) { try { final String columnPrefix = getColumnPrefix(parentPrefix, resultMapping); final ResultMap nestedResultMap = getNestedResultMap(rsw.getResultSet(), nestedResultMapId, columnPrefix); CacheKey rowKey = null; Object ancestorObject = null; if (ancestorColumnPrefix.containsKey(nestedResultMapId)) { rowKey = createRowKey(nestedResultMap, rsw, ancestorColumnPrefix.get(nestedResultMapId)); ancestorObject = ancestorObjects.get(rowKey); } if (ancestorObject != null) { if (newObject) metaObject.setValue(resultMapping.getProperty(), ancestorObject); } else { rowKey = createRowKey(nestedResultMap, rsw, columnPrefix); final CacheKey combinedKey = combineKeys(rowKey, parentRowKey); Object rowValue = nestedResultObjects.get(combinedKey); boolean knownValue = (rowValue != null); final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw.getResultSet())) { rowValue = getRowValue(rsw, nestedResultMap, combinedKey, rowKey, columnPrefix, rowValue); if (rowValue != null && !knownValue) { if (collectionProperty != null) { final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty); targetMetaObject.add(rowValue); } else { metaObject.setValue(resultMapping.getProperty(), rowValue); } foundValues = true; } } } } catch (SQLException e) { throw new ExecutorException( "Error getting nested result map values for '" + resultMapping.getProperty() + "'. Cause: " + e, e); } } } return foundValues; }
/** * 从对象中取参数 * * @param paramsObject * @param paramName * @param required * @return */ public static Object getParamValue(MetaObject paramsObject, String paramName, boolean required) { Object value = null; if (paramsObject.hasGetter(PARAMS.get(paramName))) { value = paramsObject.getValue(PARAMS.get(paramName)); } if (required && value == null) { throw new RuntimeException("分页查询缺少必要的参数:" + PARAMS.get(paramName)); } return value; }
/** * 对SQL参数(?)设值, 参考org.apache.ibatis.executor.parameter.DefaultParameterHandler。 * * @param ps 表示预编译的 SQL 语句的对象。 * @param mappedStatement MappedStatement * @param boundSql SQL * @param parameterObject 参数对象 * @throws java.sql.SQLException 数据库异常 */ @SuppressWarnings("unchecked") public static void setParameters( PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException { ErrorContext.instance() .activity("setting parameters") .object(mappedStatement.getParameterMap().getId()); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); if (parameterMappings != null) { Configuration configuration = mappedStatement.getConfiguration(); TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject); for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { Object value; String propertyName = parameterMapping.getProperty(); PropertyTokenizer prop = new PropertyTokenizer(propertyName); if (parameterObject == null) { value = null; } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else if (boundSql.hasAdditionalParameter(propertyName)) { value = boundSql.getAdditionalParameter(propertyName); } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) { value = boundSql.getAdditionalParameter(prop.getName()); if (value != null) { value = configuration .newMetaObject(value) .getValue(propertyName.substring(prop.getName().length())); } } else { value = metaObject == null ? null : metaObject.getValue(propertyName); } @SuppressWarnings("rawtypes") TypeHandler typeHandler = parameterMapping.getTypeHandler(); if (typeHandler == null) { throw new ExecutorException( "There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId()); } typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType()); } } } }
@Test public void shouldGetReadablePropertyNames() { RichType rich = new RichType(); MetaObject meta = SystemMetaObject.forObject(rich); String[] readables = meta.getGetterNames(); assertEquals(5, readables.length); for (String readable : readables) { assertTrue(meta.hasGetter(readable)); assertTrue(meta.hasGetter("richType." + readable)); } assertTrue(meta.hasGetter("richType")); }
@Test public void shouldGetWriteablePropertyNames() { RichType rich = new RichType(); MetaObject meta = SystemMetaObject.forObject(rich); String[] writeables = meta.getSetterNames(); assertEquals(5, writeables.length); for (String writeable : writeables) { assertTrue(meta.hasSetter(writeable)); assertTrue(meta.hasSetter("richType." + writeable)); } assertTrue(meta.hasSetter("richType")); }
/** * 获取动态查询条件的参数映射关系<br> * <功能详细描述> * * @param obj * @return [参数说明] * @return LinkedHashMap<String,Object> [返回类型说明] * @exception throws [异常类型] [异常说明] * @see [类、类#方法、类#成员] */ public LinkedHashMap<String, Object> getQueryCondtionParamMaps(Object obj) { final MetaObject metaObject = MetaObjectUtils.forObject(obj); final LinkedHashMap<String, Object> resMap = new LinkedHashMap<String, Object>(); for (Entry<String, String> entryTemp : queryConditionKey2SqlMapping.entrySet()) { String queryKeyName = entryTemp.getKey(); Object valueObj = metaObject.getValue(queryKeyName); if (ObjectUtils.isEmpty(valueObj)) { continue; } resMap.put(queryKeyName, valueObj); } return resMap; }
@Override public void handleResult(ResultContext context) { // TODO is that assignment always true? // 得到一条记录 // 这边黄色警告没法去掉了?因为返回Object型 final V value = (V) context.getResultObject(); // MetaObject.forObject,包装一下记录 // MetaObject是用反射来包装各种类型 final MetaObject mo = MetaObject.forObject(value, objectFactory, objectWrapperFactory); // TODO is that assignment always true? final K key = (K) mo.getValue(mapKey); mappedResults.put(key, value); // 这个类主要目的是把得到的List转为Map }
@Test public void shouldUseObjectWrapperFactoryWhenSet() { MetaObject meta = MetaObject.forObject( new Author(), SystemMetaObject.DEFAULT_OBJECT_FACTORY, new CustomBeanWrapperFactory(), new DefaultReflectorFactory()); assertTrue(meta.getObjectWrapper().getClass().equals(CustomBeanWrapper.class)); // Make sure the old default factory is in place and still works meta = SystemMetaObject.forObject(new Author()); assertFalse(meta.getObjectWrapper().getClass().equals(CustomBeanWrapper.class)); }
public Object getValue(String name) { PropertyTokenizer prop = new PropertyTokenizer(name); if (prop.hasNext()) { org.apache.ibatis.reflection.MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if (metaValue == SystemMetaObject.NULL_META_OBJECT) { return null; } else { return metaValue.getValue(prop.getChildren()); } } else { return objectWrapper.get(prop); } }
@Override public Object intercept(Invocation invocation) throws Throwable { FastResultSetHandler resultSetHandler = (FastResultSetHandler) invocation.getTarget(); MetaObject metaStatementHandler = MetaObject.forObject( resultSetHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY); RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("rowBounds"); Object result = invocation.proceed(); if (rowBounds instanceof Page) { metaStatementHandler.setValue("rowBounds.result", result); } return result; }
public Map setParameter( MappedStatement ms, Object parameterObject, PageParam page, Dialect dialect) { BoundSql boundSql = ms.getBoundSql(parameterObject); Map paramMap = null; if (parameterObject == null) { paramMap = new HashMap(); } else if (parameterObject instanceof Map) { paramMap = (Map) parameterObject; } else { paramMap = new HashMap(); boolean hasTypeHandler = ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass()); MetaObject metaObject = MetaObjectUtils.forObject(parameterObject); if (ms.getSqlSource() instanceof CustomerProviderSqlSource) { paramMap.put(Const.PROVIDER_OBJECT, parameterObject); } if (!hasTypeHandler) { for (String name : metaObject.getGetterNames()) { paramMap.put(name, metaObject.getValue(name)); } } if (boundSql.getParameterMappings() != null && boundSql.getParameterMappings().size() > 0) { for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) { String name = parameterMapping.getProperty(); if (!name.equals(Const.PARAMETER_FIRST) && !name.equals(Const.PARAMETER_SECOND) && paramMap.get(name) == null) { if (hasTypeHandler || parameterMapping.getJavaType().equals(parameterObject.getClass())) { paramMap.put(name, parameterObject); break; } } } } } // 备份原始参数对象 paramMap.put(Const.ORIGINAL_PARAMETER_OBJECT, parameterObject); // 设置分页参数 Map<String, Object> customerPageParams = dialect.getPageParameter(page); if (customerPageParams != null) { for (String key : customerPageParams.keySet()) { paramMap.put(key, customerPageParams.get(key)); } } return paramMap; }
public void setValue(String name, Object value) { PropertyTokenizer prop = new PropertyTokenizer(name); if (prop.hasNext()) { org.apache.ibatis.reflection.MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if (metaValue == SystemMetaObject.NULL_META_OBJECT) { if (value == null && prop.getChildren() != null) { return; // don't instantiate child path if value is null } else { metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory); } } metaValue.setValue(prop.getChildren(), value); } else { objectWrapper.set(prop, value); } }
private Object prepareCompositeKeyParameter( ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix) throws SQLException { final Object parameterObject = instantiateParameterObject(parameterType); final MetaObject metaObject = configuration.newMetaObject(parameterObject); boolean foundValues = false; for (ResultMapping innerResultMapping : resultMapping.getComposites()) { final Class<?> propType = metaObject.getSetterType(innerResultMapping.getProperty()); final TypeHandler<?> typeHandler = typeHandlerRegistry.getTypeHandler(propType); final Object propValue = typeHandler.getResult(rs, prependPrefix(innerResultMapping.getColumn(), columnPrefix)); if (propValue != null) { // issue #353 & #560 do not execute nested query if key is null metaObject.setValue(innerResultMapping.getProperty(), propValue); foundValues = true; } } return foundValues ? parameterObject : null; }