switched to create the PreparedStatementCreatorFactory using a list of SqlParameters to preserve type names (SPR-7699)

master
Thomas Risberg 14 years ago
parent 91debc3a35
commit 939da34869
  1. 11
      org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java
  2. 29
      org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java
  3. 18
      org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterUtilsTests.java

@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,6 +33,7 @@ import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SingleColumnRowMapper;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.SqlRowSetResultSetExtractor;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.jdbc.support.rowset.SqlRowSet;
@ -276,8 +277,8 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
ParsedSql parsedSql = getParsedSql(sql);
String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);
Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null);
int[] paramTypes = NamedParameterUtils.buildSqlTypeArray(parsedSql, paramSource);
PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, paramTypes);
List<SqlParameter> declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, paramSource);
PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, declaredParameters);
if (keyColumnNames != null) {
pscf.setGeneratedKeysColumnNames(keyColumnNames);
}
@ -313,8 +314,8 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
ParsedSql parsedSql = getParsedSql(sql);
String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);
Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null);
int[] paramTypes = NamedParameterUtils.buildSqlTypeArray(parsedSql, paramSource);
PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, paramTypes);
List<SqlParameter> declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, paramSource);
PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, declaredParameters);
return pscf.newPreparedStatementCreator(params);
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.jdbc.core.namedparam;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -320,7 +321,7 @@ public abstract class NamedParameterUtils {
}
/**
* Convert a Map of parameter types to a corresponding int array.
* Convert parameter types from an SqlParameterSource into a corresponding int array.
* This is necessary in order to reuse existing methods on JdbcTemplate.
* Any named parameter types are placed in the correct position in the
* Object array based on the parsed SQL statement info.
@ -329,14 +330,34 @@ public abstract class NamedParameterUtils {
*/
public static int[] buildSqlTypeArray(ParsedSql parsedSql, SqlParameterSource paramSource) {
int[] sqlTypes = new int[parsedSql.getTotalParameterCount()];
List paramNames = parsedSql.getParameterNames();
List<String> paramNames = parsedSql.getParameterNames();
for (int i = 0; i < paramNames.size(); i++) {
String paramName = (String) paramNames.get(i);
String paramName = paramNames.get(i);
sqlTypes[i] = paramSource.getSqlType(paramName);
}
return sqlTypes;
}
/**
* Convert parameter declarations from an SqlParameterSource to a corresponding List of SqlParameters.
* This is necessary in order to reuse existing methods on JdbcTemplate.
* The SqlParameter for a named parameter is placed in the correct position in the
* resulting list based on the parsed SQL statement info.
* @param parsedSql the parsed SQL statement
* @param paramSource the source for named parameters
*/
public static List<SqlParameter> buildSqlParameterList(ParsedSql parsedSql, SqlParameterSource paramSource) {
List<String> paramNames = parsedSql.getParameterNames();
List<SqlParameter> params = new LinkedList<SqlParameter>();
for (String paramName : paramNames) {
SqlParameter param = new SqlParameter(
paramName,
paramSource.getSqlType(paramName),
paramSource.getTypeName(paramName));
params.add(param);
}
return params;
}
//-------------------------------------------------------------------------
// Convenience methods operating on a plain SQL String

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -99,6 +99,22 @@ public class NamedParameterUtilsTests {
.buildSqlTypeArray(NamedParameterUtils.parseSqlStatement("xxx :a :b :c xx :a :b"), namedParams)[4]);
}
@Test
public void convertTypeMapToSqlParameterList() {
MapSqlParameterSource namedParams = new MapSqlParameterSource();
namedParams.addValue("a", "a", 1).addValue("b", "b", 2).addValue("c", "c", 3, "SQL_TYPE");
assertSame(3, NamedParameterUtils
.buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c"), namedParams).size());
assertSame(5, NamedParameterUtils
.buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c xx :a :b"), namedParams).size());
assertSame(5, NamedParameterUtils
.buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :a :a xx :a :a"), namedParams).size());
assertEquals(2, NamedParameterUtils
.buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c xx :a :b"), namedParams).get(4).getSqlType());
assertEquals("SQL_TYPE", NamedParameterUtils
.buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c"), namedParams).get(2).getTypeName());
}
@Test(expected = InvalidDataAccessApiUsageException.class)
public void buildValueArrayWithMissingParameterValue() throws Exception {
String sql = "select count(0) from foo where id = :id";

Loading…
Cancel
Save