Browse Source

Avoid unnecessary char[] allocation in NamedParameterUtils

Issue: SPR-11042
(cherry picked from commit 1dc7ff8)
pull/405/head
Juergen Hoeller 13 years ago
parent
commit
e1a065906e
  1. 75
      spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java

75
spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,7 +32,8 @@ import org.springframework.util.Assert;
/** /**
* Helper methods for named parameter parsing. * Helper methods for named parameter parsing.
* Only intended for internal use within Spring's JDBC framework. *
* <p>Only intended for internal use within Spring's JDBC framework.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @author Juergen Hoeller * @author Juergen Hoeller
@ -112,11 +113,13 @@ public abstract class NamedParameterUtils {
while (j < statement.length && !('}' == statement[j])) { while (j < statement.length && !('}' == statement[j])) {
j++; j++;
if (':' == statement[j] || '{' == statement[j]) { if (':' == statement[j] || '{' == statement[j]) {
throw new InvalidDataAccessApiUsageException("Parameter name contains invalid character '" + statement[j] + "' at position " + i + " in statement " + sql); throw new InvalidDataAccessApiUsageException("Parameter name contains invalid character '" +
statement[j] + "' at position " + i + " in statement: " + sql);
} }
} }
if (j >= statement.length) { if (j >= statement.length) {
throw new InvalidDataAccessApiUsageException("Non-terminated named parameter declaration at position " + i + " in statement " + sql); throw new InvalidDataAccessApiUsageException(
"Non-terminated named parameter declaration at position " + i + " in statement: " + sql);
} }
if (j - i > 3) { if (j - i > 3) {
parameter = sql.substring(i + 2, j); parameter = sql.substring(i + 2, j);
@ -165,8 +168,9 @@ public abstract class NamedParameterUtils {
return parsedSql; return parsedSql;
} }
private static int addNamedParameter(List<ParameterHolder> parameterList, int totalParameterCount, int escapes, int i, int j, private static int addNamedParameter(
String parameter) { List<ParameterHolder> parameterList, int totalParameterCount, int escapes, int i, int j, String parameter) {
parameterList.add(new ParameterHolder(parameter, i - escapes, j - escapes)); parameterList.add(new ParameterHolder(parameter, i - escapes, j - escapes));
totalParameterCount++; totalParameterCount++;
return totalParameterCount; return totalParameterCount;
@ -229,18 +233,18 @@ public abstract class NamedParameterUtils {
} }
/** /**
* Parse the SQL statement and locate any placeholders or named parameters. * Parse the SQL statement and locate any placeholders or named parameters. Named
* Named parameters are substituted for a JDBC placeholder and any select list * parameters are substituted for a JDBC placeholder, and any select list is expanded
* is expanded to the required number of placeholders. Select lists may contain * to the required number of placeholders. Select lists may contain an array of
* an array of objects and in that case the placeholders will be grouped and * objects, and in that case the placeholders will be grouped and enclosed with
* enclosed with parantheses. This allows for the use of "expression lists" in * parentheses. This allows for the use of "expression lists" in the SQL statement
* the SQL statement like:<br/> * like: <br /><br />
* select id, name, state from table where (name, age) in (('John', 35), ('Ann', 50)) * {@code select id, name, state from table where (name, age) in (('John', 35), ('Ann', 50))}
* <p>The parameter values passed in are used to determine the number of * <p>The parameter values passed in are used to determine the number of placeholders to
* placeholder to be used for a select list. Select lists should be limited * be used for a select list. Select lists should be limited to 100 or fewer elements.
* to 100 or fewer elements. A larger number of elements is not guaramteed to * A larger number of elements is not guaranteed to be supported by the database and
* be supported by the database and is strictly vendor-dependent. * is strictly vendor-dependent.
* @param parsedSql the parsed represenation of the SQL statement * @param parsedSql the parsed representation of the SQL statement
* @param paramSource the source for named parameters * @param paramSource the source for named parameters
* @return the SQL statement with substituted parameters * @return the SQL statement with substituted parameters
* @see #parseSqlStatement * @see #parseSqlStatement
@ -255,7 +259,7 @@ public abstract class NamedParameterUtils {
int[] indexes = parsedSql.getParameterIndexes(i); int[] indexes = parsedSql.getParameterIndexes(i);
int startIndex = indexes[0]; int startIndex = indexes[0];
int endIndex = indexes[1]; int endIndex = indexes[1];
actualSql.append(originalSql.substring(lastIndex, startIndex)); actualSql.append(originalSql, lastIndex, startIndex);
if (paramSource != null && paramSource.hasValue(paramName)) { if (paramSource != null && paramSource.hasValue(paramName)) {
Object value = paramSource.getValue(paramName); Object value = paramSource.getValue(paramName);
if (value instanceof SqlParameterValue) { if (value instanceof SqlParameterValue) {
@ -295,7 +299,7 @@ public abstract class NamedParameterUtils {
} }
lastIndex = endIndex; lastIndex = endIndex;
} }
actualSql.append(originalSql.substring(lastIndex, originalSql.length())); actualSql.append(originalSql, lastIndex, originalSql.length());
return actualSql.toString(); return actualSql.toString();
} }
@ -314,10 +318,10 @@ public abstract class NamedParameterUtils {
Object[] paramArray = new Object[parsedSql.getTotalParameterCount()]; Object[] paramArray = new Object[parsedSql.getTotalParameterCount()];
if (parsedSql.getNamedParameterCount() > 0 && parsedSql.getUnnamedParameterCount() > 0) { if (parsedSql.getNamedParameterCount() > 0 && parsedSql.getUnnamedParameterCount() > 0) {
throw new InvalidDataAccessApiUsageException( throw new InvalidDataAccessApiUsageException(
"You can't mix named and traditional ? placeholders. You have " + "Not allowed to mix named and traditional ? placeholders. You have " +
parsedSql.getNamedParameterCount() + " named parameter(s) and " + parsedSql.getNamedParameterCount() + " named parameter(s) and " +
parsedSql.getUnnamedParameterCount() + " traditonal placeholder(s) in [" + parsedSql.getUnnamedParameterCount() + " traditional placeholder(s) in statement: " +
parsedSql.getOriginalSql() + "]"); parsedSql.getOriginalSql());
} }
List<String> paramNames = parsedSql.getParameterNames(); List<String> paramNames = parsedSql.getParameterNames();
for (int i = 0; i < paramNames.size(); i++) { for (int i = 0; i < paramNames.size(); i++) {
@ -408,15 +412,12 @@ public abstract class NamedParameterUtils {
List<String> paramNames = parsedSql.getParameterNames(); List<String> paramNames = parsedSql.getParameterNames();
List<SqlParameter> params = new LinkedList<SqlParameter>(); List<SqlParameter> params = new LinkedList<SqlParameter>();
for (String paramName : paramNames) { for (String paramName : paramNames) {
SqlParameter param = new SqlParameter( params.add(new SqlParameter(paramName, paramSource.getSqlType(paramName), paramSource.getTypeName(paramName)));
paramName,
paramSource.getSqlType(paramName),
paramSource.getTypeName(paramName));
params.add(param);
} }
return params; return params;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Convenience methods operating on a plain SQL String // Convenience methods operating on a plain SQL String
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -463,28 +464,32 @@ public abstract class NamedParameterUtils {
return buildValueArray(parsedSql, new MapSqlParameterSource(paramMap), null); return buildValueArray(parsedSql, new MapSqlParameterSource(paramMap), null);
} }
private static class ParameterHolder { private static class ParameterHolder {
private String parameterName;
private int startIndex; private final String parameterName;
private int endIndex;
private final int startIndex;
private final int endIndex;
public ParameterHolder(String parameterName, int startIndex, int endIndex) { public ParameterHolder(String parameterName, int startIndex, int endIndex) {
super();
this.parameterName = parameterName; this.parameterName = parameterName;
this.startIndex = startIndex; this.startIndex = startIndex;
this.endIndex = endIndex; this.endIndex = endIndex;
} }
public String getParameterName() { public String getParameterName() {
return parameterName; return this.parameterName;
} }
public int getStartIndex() { public int getStartIndex() {
return startIndex; return this.startIndex;
} }
public int getEndIndex() { public int getEndIndex() {
return endIndex; return this.endIndex;
} }
} }
} }

Loading…
Cancel
Save