Example #1
0
 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;
 }
 private void resolveTypeHandler() {
   if (resultMapping.typeHandler == null && resultMapping.javaType != null) {
     Configuration configuration = resultMapping.configuration;
     TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
     resultMapping.typeHandler =
         typeHandlerRegistry.getTypeHandler(resultMapping.javaType, resultMapping.jdbcType);
   }
 }
 private Object prepareSimpleKeyParameter(
     ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix)
     throws SQLException {
   final TypeHandler<?> typeHandler;
   if (typeHandlerRegistry.hasTypeHandler(parameterType)) {
     typeHandler = typeHandlerRegistry.getTypeHandler(parameterType);
   } else {
     typeHandler = typeHandlerRegistry.getUnknownTypeHandler();
   }
   return typeHandler.getResult(rs, prependPrefix(resultMapping.getColumn(), columnPrefix));
 }
Example #4
0
 /**
  * 对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());
       }
     }
   }
 }
 private Object createResultObject(
     ResultSetWrapper rsw, ResultMap resultMap, ResultLoaderMap lazyLoader, String columnPrefix)
     throws SQLException {
   final List<Class<?>> constructorArgTypes = new ArrayList<Class<?>>();
   final List<Object> constructorArgs = new ArrayList<Object>();
   final Object resultObject =
       createResultObject(rsw, resultMap, constructorArgTypes, constructorArgs, columnPrefix);
   if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
     final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();
     for (ResultMapping propertyMapping : propertyMappings) {
       if (propertyMapping.getNestedQueryId() != null
           && propertyMapping.isLazy()) { // issue gcode #109 && issue #149
         return configuration
             .getProxyFactory()
             .createProxy(
                 resultObject,
                 lazyLoader,
                 configuration,
                 objectFactory,
                 constructorArgTypes,
                 constructorArgs);
       }
     }
   }
   return resultObject;
 }
 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 ParameterMapping oldParseMapping(
     String token, Class parameterClass, TypeHandlerRegistry typeHandlerRegistry) {
   if (token.indexOf(PARAM_DELIM) > -1) {
     StringTokenizer paramParser = new StringTokenizer(token, PARAM_DELIM, true);
     int n1 = paramParser.countTokens();
     if (n1 == 3) {
       String name = paramParser.nextToken();
       paramParser.nextToken(); // ignore ":"
       String type = paramParser.nextToken();
       TypeHandler handler;
       if (parameterClass == null) {
         handler = typeHandlerRegistry.getUnknownTypeHandler();
       } else {
         handler = resolveTypeHandler(parameterClass, name, null, JdbcType.valueOf(type));
       }
       ParameterMapping.Builder mapping =
           new ParameterMapping.Builder(configuration, name, handler);
       mapping.jdbcType(JdbcType.valueOf(type));
       return mapping.build();
     } else if (n1 >= 5) {
       throw new UnsupportedOperationException(
           "iBATIS 3 does not support null value substitution.");
     } else {
       throw new SqlMapException("Incorrect inline parameter map format: " + token);
     }
   } else {
     TypeHandler handler;
     if (parameterClass == null) {
       handler = typeHandlerRegistry.getUnknownTypeHandler();
     } else {
       handler = resolveTypeHandler(parameterClass, token, null, null);
     }
     ParameterMapping.Builder mapping =
         new ParameterMapping.Builder(configuration, token, handler);
     return mapping.build();
   }
 }
 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;
 }
 private Object createResultObject(
     ResultSetWrapper rsw,
     ResultMap resultMap,
     List<Class<?>> constructorArgTypes,
     List<Object> constructorArgs,
     String columnPrefix)
     throws SQLException {
   final Class<?> resultType = resultMap.getType();
   final List<ResultMapping> constructorMappings = resultMap.getConstructorResultMappings();
   if (typeHandlerRegistry.hasTypeHandler(resultType)) {
     return createPrimitiveResultObject(rsw, resultMap, columnPrefix);
   } else if (constructorMappings.size() > 0) {
     return createParameterizedResultObject(
         rsw, resultType, constructorMappings, constructorArgTypes, constructorArgs, columnPrefix);
   } else {
     return objectFactory.create(resultType);
   }
 }
 private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
   final ResultLoaderMap lazyLoader = new ResultLoaderMap();
   Object resultObject = createResultObject(rsw, resultMap, lazyLoader, null);
   if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
     final MetaObject metaObject = configuration.newMetaObject(resultObject);
     boolean foundValues = resultMap.getConstructorResultMappings().size() > 0;
     if (shouldApplyAutomaticMappings(
         resultMap, !AutoMappingBehavior.NONE.equals(configuration.getAutoMappingBehavior()))) {
       foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;
     }
     foundValues =
         applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
     foundValues = lazyLoader.size() > 0 || foundValues;
     resultObject = foundValues ? resultObject : null;
     return resultObject;
   }
   return resultObject;
 }
 private Object getRowValue(
     ResultSetWrapper rsw,
     ResultMap resultMap,
     CacheKey combinedKey,
     CacheKey absoluteKey,
     String columnPrefix,
     Object partialObject)
     throws SQLException {
   final String resultMapId = resultMap.getId();
   Object resultObject = partialObject;
   if (resultObject != null) {
     final MetaObject metaObject = configuration.newMetaObject(resultObject);
     putAncestor(absoluteKey, resultObject, resultMapId, columnPrefix);
     applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);
     ancestorObjects.remove(absoluteKey);
   } else {
     final ResultLoaderMap lazyLoader = new ResultLoaderMap();
     resultObject = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
     if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
       final MetaObject metaObject = configuration.newMetaObject(resultObject);
       boolean foundValues = resultMap.getConstructorResultMappings().size() > 0;
       if (shouldApplyAutomaticMappings(
           resultMap, AutoMappingBehavior.FULL.equals(configuration.getAutoMappingBehavior()))) {
         foundValues =
             applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
       }
       foundValues =
           applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix)
               || foundValues;
       putAncestor(absoluteKey, resultObject, resultMapId, columnPrefix);
       foundValues =
           applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true)
               || foundValues;
       ancestorObjects.remove(absoluteKey);
       foundValues = lazyLoader.size() > 0 || foundValues;
       resultObject = foundValues ? resultObject : null;
     }
     if (combinedKey != CacheKey.NULL_CACHE_KEY)
       nestedResultObjects.put(combinedKey, resultObject);
   }
   return resultObject;
 }
 public void setParameters(PreparedStatement ps) throws SQLException {
   ErrorContext.instance()
       .activity("setting parameters")
       .object(mappedStatement.getParameterMap().getId());
   List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
   if (parameterMappings != null) {
     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();
         if (boundSql.hasAdditionalParameter(
             propertyName)) { // issue #448 ask first for additional params
           value = boundSql.getAdditionalParameter(propertyName);
         } else if (parameterObject == null) {
           value = null;
         } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
           value = parameterObject;
         } else {
           value = metaObject == null ? null : metaObject.getValue(propertyName);
         }
         TypeHandler typeHandler = parameterMapping.getTypeHandler();
         if (typeHandler == null) {
           throw new ExecutorException(
               "There was no TypeHandler found for parameter "
                   + propertyName
                   + " of statement "
                   + mappedStatement.getId());
         }
         JdbcType jdbcType = parameterMapping.getJdbcType();
         if (value == null && jdbcType == null) jdbcType = configuration.getJdbcTypeForNull();
         typeHandler.setParameter(ps, i + 1, value, jdbcType);
       }
     }
   }
 }
  private TypeHandler resolveTypeHandler(
      Class clazz, String propertyName, String javaType, JdbcType jdbcType) {
    TypeHandler handler;
    if (clazz == null) {
      // Unknown
      handler = typeHandlerRegistry.getUnknownTypeHandler();
    } else if (java.util.Map.class.isAssignableFrom(clazz)) {
      // Map
      if (javaType == null) {
        handler = typeHandlerRegistry.getUnknownTypeHandler(); // BUG 1012591 -
        // typeHandlerRegistry.getTypeHandler(java.lang.Object.class, jdbcType);
      } else {
        try {
          Class javaClass = typeAliasRegistry.resolveAlias(javaType);
          handler = typeHandlerRegistry.getTypeHandler(javaClass, jdbcType);
        } catch (Exception e) {
          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
        }
      }
    } else if (typeHandlerRegistry.getTypeHandler(clazz, jdbcType) != null) {
      // Primitive
      handler = typeHandlerRegistry.getTypeHandler(clazz, jdbcType);
    } else {
      // JavaBean
      if (javaType == null) {

        Class type = MetaClass.forClass(clazz).getGetterType(propertyName);
        handler = typeHandlerRegistry.getTypeHandler(type, jdbcType);

      } else {
        try {
          Class javaClass = typeAliasRegistry.resolveAlias(javaType);
          handler = typeHandlerRegistry.getTypeHandler(javaClass, jdbcType);
        } catch (Exception e) {
          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
        }
      }
    }
    return handler;
  }
  private ParameterMapping newParseMapping(String token, Class parameterClass) {

    // #propertyName,javaType=string,jdbcType=VARCHAR,mode=IN,nullValue=N/A,handler=string,numericScale=2#

    StringTokenizer paramParser = new StringTokenizer(token, "=, ", false);
    String propertyName = paramParser.nextToken();
    TypeHandler typeHandler = null;
    Class javaType = null;
    JdbcType jdbcType = null;
    ParameterMode parameterMode = null;
    Integer numericScale = null;

    while (paramParser.hasMoreTokens()) {
      String field = paramParser.nextToken();
      if (paramParser.hasMoreTokens()) {
        String value = paramParser.nextToken();
        if ("javaType".equals(field)) {
          try {
            javaType = typeAliasRegistry.resolveAlias(value);
          } catch (Exception e) {
            throw new SqlMapException("Error loading javaType class");
          }
        } else if ("jdbcType".equals(field)) {
          jdbcType = JdbcType.valueOf(value);
        } else if ("mode".equals(field)) {
          parameterMode = ParameterMode.valueOf(value);
        } else if ("nullValue".equals(field)) {
          throw new UnsupportedOperationException(
              "iBATIS 3 does not support null value substitution.");
        } else if ("handler".equals(field)) {
          try {
            Object impl = typeAliasRegistry.resolveAlias(value).newInstance();
            typeHandler = ((TypeHandler) impl);
          } catch (Exception e) {
            throw new SqlMapException(
                "Error loading class specified by handler field in " + token + ".  Cause: " + e, e);
          }
        } else if ("numericScale".equals(field)) {
          try {
            numericScale = Integer.valueOf(value);
            if (numericScale < 0) {
              throw new SqlMapException(
                  "Value specified for numericScale must be greater than or equal to zero");
            }
          } catch (NumberFormatException e) {
            throw new SqlMapException("Value specified for numericScale is not a valid Integer");
          }
        } else {
          throw new SqlMapException(
              "Unrecognized parameter mapping field: '" + field + "' in " + token);
        }
      } else {
        throw new SqlMapException(
            "Incorrect inline parameter map format (missmatched name=value pairs): " + token);
      }
    }

    if (typeHandler == null) {
      if (parameterClass == null) {
        typeHandler = typeHandlerRegistry.getUnknownTypeHandler();
      } else {
        String javaTypeString = javaType == null ? null : javaType.getName();
        typeHandler = resolveTypeHandler(parameterClass, propertyName, javaTypeString, jdbcType);
      }
    }

    if (propertyName != null && propertyName.startsWith("[")) {
      propertyName = "_collection" + propertyName;
    }

    ParameterMapping.Builder mapping =
        new ParameterMapping.Builder(configuration, propertyName, typeHandler);
    mapping.javaType(javaType);
    mapping.jdbcType(jdbcType);
    mapping.mode(parameterMode);
    mapping.numericScale(numericScale);

    return mapping.build();
  }