Initial import of JDBC module
This commit is contained in:
		
							parent
							
								
									8c87d84728
								
							
						
					
					
						commit
						c236f9fac7
					
				| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project name="org.springframework.jdbc">
 | 
			
		||||
	<property file="${basedir}/../build.properties"/>
 | 
			
		||||
	<import file="${basedir}/../build-spring-framework/package-bundle.xml"/>
 | 
			
		||||
	<import file="${basedir}/../spring-build/standard/default.xml"/>
 | 
			
		||||
</project>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?>
 | 
			
		||||
<ivy-module
 | 
			
		||||
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
		xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd"
 | 
			
		||||
		version="1.3">
 | 
			
		||||
 | 
			
		||||
	<info organisation="org.springframework" module="${ant.project.name}">
 | 
			
		||||
		<license name="Apache 2.0" url="http://www.apache.org/licenses/LICENSE-2.0"/>
 | 
			
		||||
	</info>
 | 
			
		||||
 | 
			
		||||
	<configurations>
 | 
			
		||||
		<include file="${spring.build.dir}/common/default-ivy-configurations.xml"/>
 | 
			
		||||
	</configurations>
 | 
			
		||||
 | 
			
		||||
	<publications>
 | 
			
		||||
		<artifact name="${ant.project.name}"/>
 | 
			
		||||
		<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
 | 
			
		||||
	</publications>
 | 
			
		||||
 | 
			
		||||
	<dependencies>
 | 
			
		||||
		<!-- compile dependencies -->
 | 
			
		||||
		<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile->runtime" />
 | 
			
		||||
		<dependency org="org.springframework" name="org.springframework.core" rev="latest.integration" conf="compile->compile" />
 | 
			
		||||
		<dependency org="org.springframework" name="org.springframework.beans" rev="latest.integration" conf="compile->compile" />
 | 
			
		||||
		<dependency org="org.springframework" name="org.springframework.aop" rev="latest.integration" conf="compile->compile" />
 | 
			
		||||
		<dependency org="org.springframework" name="org.springframework.transaction" rev="latest.integration" conf="compile->compile" />
 | 
			
		||||
		<!-- optional dependencies -->
 | 
			
		||||
		<dependency org="org.springframework" name="org.springframework.context" rev="latest.integration" conf="optional->compile" />
 | 
			
		||||
		<dependency org="javax.transaction" name="com.springsource.javax.transaction" rev="1.1.0" conf="optional->compile" />
 | 
			
		||||
		<dependency org="com.mchange.c3p0" name="com.springsource.com.mchange.v2.c3p0" rev="0.9.1.2" conf="optional->compile" />
 | 
			
		||||
		<dependency org="com.experlog.xapool" name="com.springsource.org.enhydra.jdbc" rev="1.5.0" conf="optional->compile" />
 | 
			
		||||
		<!-- test dependencies -->
 | 
			
		||||
		<dependency org="org.junit" name="com.springsource.org.junit" rev="4.4.0" conf="test->runtime" />
 | 
			
		||||
				
 | 
			
		||||
	</dependencies>
 | 
			
		||||
 | 
			
		||||
</ivy-module>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
<?xml version="1.0"?>
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 | 
			
		||||
	<modelVersion>4.0.0</modelVersion>
 | 
			
		||||
	<groupId>org.springframework</groupId>
 | 
			
		||||
	<artifactId>org.springframework.core</artifactId>
 | 
			
		||||
	<packaging>jar</packaging>
 | 
			
		||||
	<name>Spring Core Abstractions and Utilities</name>
 | 
			
		||||
	<version>3.0.0.M1</version>
 | 
			
		||||
	<repositories>
 | 
			
		||||
		<repository>
 | 
			
		||||
			<id>com.springsource.repository.bundles.external</id>
 | 
			
		||||
			<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
 | 
			
		||||
			<url>http://repository.springsource.com/maven/bundles/external</url>
 | 
			
		||||
		</repository>		
 | 
			
		||||
	</repositories>
 | 
			
		||||
	<build>
 | 
			
		||||
        <plugins>
 | 
			
		||||
            <plugin>
 | 
			
		||||
                <groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
                <artifactId>maven-compiler-plugin</artifactId>
 | 
			
		||||
                <configuration>
 | 
			
		||||
                    <source>1.5</source>
 | 
			
		||||
                    <target>1.5</target>
 | 
			
		||||
                </configuration>
 | 
			
		||||
            </plugin>
 | 
			
		||||
		</plugins>
 | 
			
		||||
	</build>
 | 
			
		||||
	<dependencies>
 | 
			
		||||
		<dependency>
 | 
			
		||||
		    <groupId>org.apache.commons</groupId>
 | 
			
		||||
		    <artifactId>com.springsource.org.apache.commons.logging</artifactId>
 | 
			
		||||
		    <version>1.1.1</version>
 | 
			
		||||
		</dependency>
 | 
			
		||||
		<dependency>
 | 
			
		||||
		    <groupId>org.apache.log4j</groupId>
 | 
			
		||||
		    <artifactId>com.springsource.org.apache.log4j</artifactId>
 | 
			
		||||
		    <version>1.2.15</version>
 | 
			
		||||
			<optional>true</optional>
 | 
			
		||||
		</dependency>
 | 
			
		||||
		<dependency>
 | 
			
		||||
			<groupId>org.apache.commons</groupId>
 | 
			
		||||
			<artifactId>com.springsource.org.apache.commons.collections</artifactId>
 | 
			
		||||
			<version>3.2.0</version>
 | 
			
		||||
			<optional>true</optional>
 | 
			
		||||
		</dependency>
 | 
			
		||||
		<dependency>
 | 
			
		||||
			<groupId>org.aspectj</groupId>
 | 
			
		||||
			<artifactId>com.springsource.org.aspectj.weaver</artifactId>
 | 
			
		||||
			<version>1.6.2.RELEASE</version>
 | 
			
		||||
			<optional>true</optional>
 | 
			
		||||
		</dependency>
 | 
			
		||||
		<dependency>
 | 
			
		||||
			<groupId>org.objectweb.asm</groupId>
 | 
			
		||||
			<artifactId>com.springsource.org.objectweb.asm.commons</artifactId>
 | 
			
		||||
			<version>2.2.3</version>
 | 
			
		||||
			<optional>true</optional>
 | 
			
		||||
		</dependency>
 | 
			
		||||
	</dependencies>
 | 
			
		||||
</project>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception thrown when SQL specified is invalid. Such exceptions always have
 | 
			
		||||
 * a <code>java.sql.SQLException</code> root cause.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>It would be possible to have subclasses for no such table, no such column etc.
 | 
			
		||||
 * A custom SQLExceptionTranslator could create such more specific exceptions,
 | 
			
		||||
 * without affecting code using this class.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @see InvalidResultSetAccessException
 | 
			
		||||
 */
 | 
			
		||||
public class BadSqlGrammarException extends InvalidDataAccessResourceUsageException {
 | 
			
		||||
	
 | 
			
		||||
	private String sql;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for BadSqlGrammarException.
 | 
			
		||||
	 * @param task name of current task
 | 
			
		||||
	 * @param sql the offending SQL statement
 | 
			
		||||
	 * @param ex the root cause
 | 
			
		||||
	 */
 | 
			
		||||
	public BadSqlGrammarException(String task, String sql, SQLException ex) {
 | 
			
		||||
		super(task + "; bad SQL grammar [" + sql + "]", ex);
 | 
			
		||||
		this.sql = sql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the wrapped SQLException.
 | 
			
		||||
	 */
 | 
			
		||||
	public SQLException getSQLException() {
 | 
			
		||||
		return (SQLException) getCause();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQL that caused the problem.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSql() {
 | 
			
		||||
		return this.sql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessResourceFailureException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fatal exception thrown when we can't connect to an RDBMS using JDBC.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 */
 | 
			
		||||
public class CannotGetJdbcConnectionException extends DataAccessResourceFailureException {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for CannotGetJdbcConnectionException.
 | 
			
		||||
	 * @param msg the detail message
 | 
			
		||||
	 * @param ex SQLException root cause
 | 
			
		||||
	 */
 | 
			
		||||
	public CannotGetJdbcConnectionException(String msg, SQLException ex) {
 | 
			
		||||
		super(msg, ex);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for CannotGetJdbcConnectionException.
 | 
			
		||||
	 * @param msg the detail message
 | 
			
		||||
	 * @param ex ClassNotFoundException root cause
 | 
			
		||||
	 * @deprecated since Spring 2.5, in favor of throwing an
 | 
			
		||||
	 * IllegalStateException in case of the driver not being found
 | 
			
		||||
	 */
 | 
			
		||||
	public CannotGetJdbcConnectionException(String msg, ClassNotFoundException ex) {
 | 
			
		||||
		super(msg, ex);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataRetrievalFailureException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Data access exception thrown when a result set did not have the correct column count,
 | 
			
		||||
 * for example when expecting a single column but getting 0 or more than 1 columns.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
 */
 | 
			
		||||
public class IncorrectResultSetColumnCountException extends DataRetrievalFailureException {
 | 
			
		||||
 | 
			
		||||
	private int expectedCount;
 | 
			
		||||
 | 
			
		||||
	private int actualCount;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for IncorrectResultSetColumnCountException.
 | 
			
		||||
	 * @param expectedCount the expected column count
 | 
			
		||||
	 * @param actualCount the actual column count
 | 
			
		||||
	 */
 | 
			
		||||
	public IncorrectResultSetColumnCountException(int expectedCount, int actualCount) {
 | 
			
		||||
		super("Incorrect column count: expected " + expectedCount + ", actual " + actualCount);
 | 
			
		||||
		this.expectedCount = expectedCount;
 | 
			
		||||
		this.actualCount = actualCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for IncorrectResultCountDataAccessException.
 | 
			
		||||
	 * @param msg the detail message
 | 
			
		||||
	 * @param expectedCount the expected column count
 | 
			
		||||
	 * @param actualCount the actual column count
 | 
			
		||||
	 */
 | 
			
		||||
	public IncorrectResultSetColumnCountException(String msg, int expectedCount, int actualCount) {
 | 
			
		||||
		super(msg);
 | 
			
		||||
		this.expectedCount = expectedCount;
 | 
			
		||||
		this.actualCount = actualCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the expected column count.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getExpectedCount() {
 | 
			
		||||
		return this.expectedCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the actual column count.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getActualCount() {
 | 
			
		||||
		return this.actualCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception thrown when a ResultSet has been accessed in an invalid fashion.
 | 
			
		||||
 * Such exceptions always have a <code>java.sql.SQLException</code> root cause.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This typically happens when an invalid ResultSet column index or name
 | 
			
		||||
 * has been specified. Also thrown by disconnected SqlRowSets.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.2
 | 
			
		||||
 * @see BadSqlGrammarException
 | 
			
		||||
 * @see org.springframework.jdbc.support.rowset.SqlRowSet
 | 
			
		||||
 */
 | 
			
		||||
public class InvalidResultSetAccessException extends InvalidDataAccessResourceUsageException {
 | 
			
		||||
 | 
			
		||||
	private String sql;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for InvalidResultSetAccessException.
 | 
			
		||||
	 * @param task name of current task
 | 
			
		||||
	 * @param sql the offending SQL statement
 | 
			
		||||
	 * @param ex the root cause
 | 
			
		||||
	 */
 | 
			
		||||
	public InvalidResultSetAccessException(String task, String sql, SQLException ex) {
 | 
			
		||||
		super(task + "; invalid ResultSet access for SQL [" + sql + "]", ex);
 | 
			
		||||
		this.sql = sql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for InvalidResultSetAccessException.
 | 
			
		||||
	 * @param ex the root cause
 | 
			
		||||
	 */
 | 
			
		||||
	public InvalidResultSetAccessException(SQLException ex) {
 | 
			
		||||
		super(ex.getMessage(), ex);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the wrapped SQLException.
 | 
			
		||||
	 */
 | 
			
		||||
	public SQLException getSQLException() {
 | 
			
		||||
		return (SQLException) getCause();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQL that caused the problem.
 | 
			
		||||
	 * @return the offending SQL, if known
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSql() {
 | 
			
		||||
		return this.sql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception thrown when a JDBC update affects an unexpected number of rows.
 | 
			
		||||
 * Typically we expect an update to affect a single row, meaning it's an
 | 
			
		||||
 * error if it affects multiple rows.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 */
 | 
			
		||||
public class JdbcUpdateAffectedIncorrectNumberOfRowsException extends IncorrectUpdateSemanticsDataAccessException {
 | 
			
		||||
 | 
			
		||||
	/** Number of rows that should have been affected */
 | 
			
		||||
	private int expected;
 | 
			
		||||
 | 
			
		||||
	/** Number of rows that actually were affected */
 | 
			
		||||
	private int actual;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for JdbcUpdateAffectedIncorrectNumberOfRowsException.
 | 
			
		||||
	 * @param sql SQL we were tring to execute
 | 
			
		||||
	 * @param expected the expected number of rows affected
 | 
			
		||||
	 * @param actual the actual number of rows affected
 | 
			
		||||
	 */
 | 
			
		||||
	public JdbcUpdateAffectedIncorrectNumberOfRowsException(String sql, int expected, int actual) {
 | 
			
		||||
		super("SQL update '" + sql + "' affected " + actual + " rows, not " + expected + " as expected");
 | 
			
		||||
		this.expected = expected;
 | 
			
		||||
		this.actual = actual;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the number of rows that should have been affected.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getExpectedRowsAffected() {
 | 
			
		||||
		return this.expected;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the number of rows that have actually been affected.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getActualRowsAffected() {
 | 
			
		||||
		return this.actual;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean wasDataUpdated() {
 | 
			
		||||
		return (getActualRowsAffected() > 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataRetrievalFailureException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception to be thrown when a LOB could not be retrieved.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.0.2
 | 
			
		||||
 */
 | 
			
		||||
public class LobRetrievalFailureException extends DataRetrievalFailureException {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for LobRetrievalFailureException.
 | 
			
		||||
	 * @param msg the detail message
 | 
			
		||||
	 */
 | 
			
		||||
	public LobRetrievalFailureException(String msg) {
 | 
			
		||||
		super(msg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for LobRetrievalFailureException.
 | 
			
		||||
	 * @param msg the detail message
 | 
			
		||||
	 * @param ex IOException root cause
 | 
			
		||||
	 */
 | 
			
		||||
	public LobRetrievalFailureException(String msg, IOException ex) {
 | 
			
		||||
		super(msg, ex);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import java.sql.SQLWarning;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.UncategorizedDataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception thrown when we're not ignoring {@link java.sql.SQLWarning SQLWarnings}.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>If a SQLWarning is reported, the operation completed, so we will need
 | 
			
		||||
 * to explicitly roll it back if we're not happy when looking at the warning.
 | 
			
		||||
 * We might choose to ignore (and log) the warning, or to wrap and throw it
 | 
			
		||||
 * in the shape of this SQLWarningException instead.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcTemplate#setIgnoreWarnings
 | 
			
		||||
 */
 | 
			
		||||
public class SQLWarningException extends UncategorizedDataAccessException {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for SQLWarningException.
 | 
			
		||||
	 * @param msg the detail message
 | 
			
		||||
	 * @param ex the JDBC warning
 | 
			
		||||
	 */
 | 
			
		||||
	public SQLWarningException(String msg, SQLWarning ex) {
 | 
			
		||||
		super(msg, ex);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the underlying SQLWarning.
 | 
			
		||||
	 */
 | 
			
		||||
	public SQLWarning SQLWarning() {
 | 
			
		||||
		return (SQLWarning) getCause();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc;
 | 
			
		||||
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.UncategorizedDataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception thrown when we can't classify a SQLException into 
 | 
			
		||||
 * one of our generic data access exceptions.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 */
 | 
			
		||||
public class UncategorizedSQLException extends UncategorizedDataAccessException {
 | 
			
		||||
 | 
			
		||||
	/** SQL that led to the problem */
 | 
			
		||||
	private final String sql;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for UncategorizedSQLException.
 | 
			
		||||
	 * @param task name of current task
 | 
			
		||||
	 * @param sql the offending SQL statement
 | 
			
		||||
	 * @param ex the root cause
 | 
			
		||||
	 */
 | 
			
		||||
	public UncategorizedSQLException(String task, String sql, SQLException ex) {
 | 
			
		||||
		super(task + "; uncategorized SQLException for SQL [" + sql + "]; SQL state [" +
 | 
			
		||||
				ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " + ex.getMessage(), ex);
 | 
			
		||||
		this.sql = sql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the underlying SQLException.
 | 
			
		||||
	 */
 | 
			
		||||
	public SQLException getSQLException() {
 | 
			
		||||
		return (SQLException) getCause();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQL that led to the problem.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSql() {
 | 
			
		||||
		return this.sql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Simple adapter for PreparedStatementSetter that applies
 | 
			
		||||
 * a given array of arguments.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 */
 | 
			
		||||
class ArgPreparedStatementSetter implements PreparedStatementSetter, ParameterDisposer {
 | 
			
		||||
 | 
			
		||||
	private final Object[] args;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ArgPreparedStatementSetter for the given arguments.
 | 
			
		||||
	 * @param args the arguments to set
 | 
			
		||||
	 */
 | 
			
		||||
	public ArgPreparedStatementSetter(Object[] args) {
 | 
			
		||||
		this.args = args;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public void setValues(PreparedStatement ps) throws SQLException {
 | 
			
		||||
		if (this.args != null) {
 | 
			
		||||
			for (int i = 0; i < this.args.length; i++) {
 | 
			
		||||
				Object arg = this.args[i];
 | 
			
		||||
				if (arg instanceof SqlParameterValue) {
 | 
			
		||||
					SqlParameterValue paramValue = (SqlParameterValue) arg;
 | 
			
		||||
					StatementCreatorUtils.setParameterValue(ps, i + 1, paramValue, paramValue.getValue());
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					StatementCreatorUtils.setParameterValue(ps, i + 1, SqlTypeValue.TYPE_UNKNOWN, arg);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void cleanupParameters() {
 | 
			
		||||
		StatementCreatorUtils.cleanupParameters(this.args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Simple adapter for PreparedStatementSetter that applies
 | 
			
		||||
 * given arrays of arguments and JDBC argument types.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 */
 | 
			
		||||
class ArgTypePreparedStatementSetter implements PreparedStatementSetter, ParameterDisposer {
 | 
			
		||||
 | 
			
		||||
	private final Object[] args;
 | 
			
		||||
 | 
			
		||||
	private final int[] argTypes;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ArgTypePreparedStatementSetter for the given arguments.
 | 
			
		||||
	 * @param args the arguments to set
 | 
			
		||||
	 * @param argTypes the corresponding SQL types of the arguments
 | 
			
		||||
	 */
 | 
			
		||||
	public ArgTypePreparedStatementSetter(Object[] args, int[] argTypes) {
 | 
			
		||||
		if ((args != null && argTypes == null) || (args == null && argTypes != null) ||
 | 
			
		||||
				(args != null && args.length != argTypes.length)) {
 | 
			
		||||
			throw new InvalidDataAccessApiUsageException("args and argTypes parameters must match");
 | 
			
		||||
		}
 | 
			
		||||
		this.args = args;
 | 
			
		||||
		this.argTypes = argTypes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public void setValues(PreparedStatement ps) throws SQLException {
 | 
			
		||||
		int argIndx = 1;
 | 
			
		||||
		if (this.args != null) {
 | 
			
		||||
			for (int i = 0; i < this.args.length; i++) {
 | 
			
		||||
				Object arg = this.args[i];
 | 
			
		||||
				if (arg instanceof Collection && this.argTypes[i] != Types.ARRAY) {
 | 
			
		||||
					Collection entries = (Collection) arg;
 | 
			
		||||
					for (Iterator it = entries.iterator(); it.hasNext();) {
 | 
			
		||||
						Object entry = it.next();
 | 
			
		||||
						if (entry instanceof Object[]) {
 | 
			
		||||
							Object[] valueArray = ((Object[])entry);
 | 
			
		||||
							for (int k = 0; k < valueArray.length; k++) {
 | 
			
		||||
								Object argValue = valueArray[k];
 | 
			
		||||
								StatementCreatorUtils.setParameterValue(ps, argIndx++, this.argTypes[i], argValue);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							StatementCreatorUtils.setParameterValue(ps, argIndx++, this.argTypes[i], entry);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					StatementCreatorUtils.setParameterValue(ps, argIndx++, this.argTypes[i], arg);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void cleanupParameters() {
 | 
			
		||||
		StatementCreatorUtils.cleanupParameters(this.args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Batch update callback interface used by the {@link JdbcTemplate} class.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This interface sets values on a {@link java.sql.PreparedStatement} provided
 | 
			
		||||
 * by the JdbcTemplate class, for each of a number of updates in a batch using the
 | 
			
		||||
 * same SQL. Implementations are responsible for setting any necessary parameters.
 | 
			
		||||
 * SQL with placeholders will already have been supplied.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Implementations <i>do not</i> need to concern themselves with SQLExceptions
 | 
			
		||||
 * that may be thrown from operations they attempt. The JdbcTemplate class will
 | 
			
		||||
 * catch and handle SQLExceptions appropriately.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @since March 2, 2003
 | 
			
		||||
 * @see JdbcTemplate#batchUpdate(String, BatchPreparedStatementSetter)
 | 
			
		||||
 * @see InterruptibleBatchPreparedStatementSetter
 | 
			
		||||
 */
 | 
			
		||||
public interface BatchPreparedStatementSetter {
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Set parameter values on the given PreparedStatement.
 | 
			
		||||
	 * @param ps the PreparedStatement to invoke setter methods on
 | 
			
		||||
	 * @param i index of the statement we're issuing in the batch, starting from 0
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered
 | 
			
		||||
	 * (i.e. there is no need to catch SQLException)
 | 
			
		||||
	 */
 | 
			
		||||
	void setValues(PreparedStatement ps, int i) throws SQLException;
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Return the size of the batch.
 | 
			
		||||
	 * @return the number of statements in the batch
 | 
			
		||||
	 */
 | 
			
		||||
	int getBatchSize();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,270 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.beans.PropertyDescriptor;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.ResultSetMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.BeanUtils;
 | 
			
		||||
import org.springframework.beans.BeanWrapper;
 | 
			
		||||
import org.springframework.beans.NotWritablePropertyException;
 | 
			
		||||
import org.springframework.beans.PropertyAccessorFactory;
 | 
			
		||||
import org.springframework.dao.DataRetrievalFailureException;
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link RowMapper} implementation that converts a row into a new instance
 | 
			
		||||
 * of the specified mapped target class. The mapped target class must be a
 | 
			
		||||
 * top-level class and it must have a default or no-arg constructor.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Column values are mapped based on matching the column name as obtained from result set
 | 
			
		||||
 * metadata to public setters for the corresponding properties. The names are matched either
 | 
			
		||||
 * directly or by transforming a name separating the parts with underscores to the same name
 | 
			
		||||
 * using "camel" case.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Mapping is provided for fields in the target class for many common types, e.g.:
 | 
			
		||||
 * String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long,
 | 
			
		||||
 * float, Float, double, Double, BigDecimal, <code>java.util.Date</code>, etc.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>To facilitate mapping between columns and fields that don't have matching names,
 | 
			
		||||
 * try using column aliases in the SQL statement like "select fname as first_name from customer".
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Please note that this class is designed to provide convenience rather than high performance.
 | 
			
		||||
 * For best performance consider using a custom RowMapper.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class BeanPropertyRowMapper implements RowMapper {
 | 
			
		||||
 | 
			
		||||
	/** Logger available to subclasses */
 | 
			
		||||
	protected final Log logger = LogFactory.getLog(getClass());
 | 
			
		||||
 | 
			
		||||
	/** The class we are mapping to */
 | 
			
		||||
	private Class mappedClass;
 | 
			
		||||
 | 
			
		||||
	/** Whether we're strictly validating */
 | 
			
		||||
	private boolean checkFullyPopulated = false;
 | 
			
		||||
 | 
			
		||||
	/** Map of the fields we provide mapping for */
 | 
			
		||||
	private Map mappedFields;
 | 
			
		||||
 | 
			
		||||
	/** Set of bean properties we provide mapping for */
 | 
			
		||||
	private Set mappedProperties;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BeanPropertyRowMapper for bean-style configuration.
 | 
			
		||||
	 * @see #setMappedClass
 | 
			
		||||
	 * @see #setCheckFullyPopulated
 | 
			
		||||
	 */
 | 
			
		||||
	public BeanPropertyRowMapper() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BeanPropertyRowMapper, accepting unpopulated properties
 | 
			
		||||
	 * in the target bean.
 | 
			
		||||
	 * @param mappedClass the class that each row should be mapped to
 | 
			
		||||
	 */
 | 
			
		||||
	public BeanPropertyRowMapper(Class mappedClass) {
 | 
			
		||||
		initialize(mappedClass);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BeanPropertyRowMapper.
 | 
			
		||||
	 * @param mappedClass the class that each row should be mapped to
 | 
			
		||||
	 * @param checkFullyPopulated whether we're strictly validating that
 | 
			
		||||
	 * all bean properties have been mapped from corresponding database fields
 | 
			
		||||
	 */
 | 
			
		||||
	public BeanPropertyRowMapper(Class mappedClass, boolean checkFullyPopulated) {
 | 
			
		||||
		initialize(mappedClass);
 | 
			
		||||
		this.checkFullyPopulated = checkFullyPopulated;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the class that each row should be mapped to.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setMappedClass(Class mappedClass) {
 | 
			
		||||
		if (this.mappedClass == null) {
 | 
			
		||||
			initialize(mappedClass);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (!this.mappedClass.equals(mappedClass)) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException("The mapped class can not be reassigned to map to " +
 | 
			
		||||
						mappedClass + " since it is already providing mapping for " + this.mappedClass);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize the mapping metadata for the given class.
 | 
			
		||||
	 * @param mappedClass the mapped class.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void initialize(Class mappedClass) {
 | 
			
		||||
		this.mappedClass = mappedClass;
 | 
			
		||||
		this.mappedFields = new HashMap();
 | 
			
		||||
		this.mappedProperties = new HashSet();
 | 
			
		||||
		PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass);
 | 
			
		||||
		for (int i = 0; i < pds.length; i++) {
 | 
			
		||||
			PropertyDescriptor pd = pds[i];
 | 
			
		||||
			if (pd.getWriteMethod() != null) {
 | 
			
		||||
				this.mappedFields.put(pd.getName().toLowerCase(), pd);
 | 
			
		||||
				String underscoredName = underscoreName(pd.getName());
 | 
			
		||||
				if (!pd.getName().toLowerCase().equals(underscoredName)) {
 | 
			
		||||
					this.mappedFields.put(underscoredName, pd);
 | 
			
		||||
				}
 | 
			
		||||
				this.mappedProperties.add(pd.getName());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert a name in camelCase to an underscored name in lower case.
 | 
			
		||||
	 * Any upper case letters are converted to lower case with a preceding underscore.
 | 
			
		||||
	 * @param name the string containing original name
 | 
			
		||||
	 * @return the converted name
 | 
			
		||||
	 */
 | 
			
		||||
	private String underscoreName(String name) {
 | 
			
		||||
		StringBuffer result = new StringBuffer();
 | 
			
		||||
		if (name != null && name.length() > 0) {
 | 
			
		||||
			result.append(name.substring(0, 1).toLowerCase());
 | 
			
		||||
			for (int i = 1; i < name.length(); i++) {
 | 
			
		||||
				String s = name.substring(i, i + 1);
 | 
			
		||||
				if (s.equals(s.toUpperCase())) {
 | 
			
		||||
					result.append("_");
 | 
			
		||||
					result.append(s.toLowerCase());
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					result.append(s);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the class that we are mapping to.
 | 
			
		||||
	 */
 | 
			
		||||
	public final Class getMappedClass() {
 | 
			
		||||
		return this.mappedClass;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether we're strictly validating that all bean properties have been
 | 
			
		||||
	 * mapped from corresponding database fields.
 | 
			
		||||
	 * <p>Default is <code>false</code>, accepting unpopulated properties in the
 | 
			
		||||
	 * target bean.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setCheckFullyPopulated(boolean checkFullyPopulated) {
 | 
			
		||||
		this.checkFullyPopulated = checkFullyPopulated;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether we're strictly validating that all bean properties have been
 | 
			
		||||
	 * mapped from corresponding database fields.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isCheckFullyPopulated() {
 | 
			
		||||
		return this.checkFullyPopulated;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Extract the values for all columns in the current row.
 | 
			
		||||
	 * <p>Utilizes public setters and result set metadata.
 | 
			
		||||
	 * @see java.sql.ResultSetMetaData
 | 
			
		||||
	 */
 | 
			
		||||
	public Object mapRow(ResultSet rs, int rowNumber) throws SQLException {
 | 
			
		||||
		Assert.state(this.mappedClass != null, "Mapped class was not specified");
 | 
			
		||||
		Object mappedObject = BeanUtils.instantiateClass(this.mappedClass);
 | 
			
		||||
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);
 | 
			
		||||
		initBeanWrapper(bw);
 | 
			
		||||
 | 
			
		||||
		ResultSetMetaData rsmd = rs.getMetaData();
 | 
			
		||||
		int columnCount = rsmd.getColumnCount();
 | 
			
		||||
		Set populatedProperties = (isCheckFullyPopulated() ? new HashSet() : null);
 | 
			
		||||
 | 
			
		||||
		for (int index = 1; index <= columnCount; index++) {
 | 
			
		||||
			String column = JdbcUtils.lookupColumnName(rsmd, index).toLowerCase();
 | 
			
		||||
			PropertyDescriptor pd = (PropertyDescriptor) this.mappedFields.get(column);
 | 
			
		||||
			if (pd != null) {
 | 
			
		||||
				try {
 | 
			
		||||
					Object value = getColumnValue(rs, index, pd);
 | 
			
		||||
					if (logger.isDebugEnabled() && rowNumber == 0) {
 | 
			
		||||
						logger.debug("Mapping column '" + column + "' to property '" +
 | 
			
		||||
								pd.getName() + "' of type " + pd.getPropertyType());
 | 
			
		||||
					}
 | 
			
		||||
					bw.setPropertyValue(pd.getName(), value);
 | 
			
		||||
					if (populatedProperties != null) {
 | 
			
		||||
						populatedProperties.add(pd.getName());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				catch (NotWritablePropertyException ex) {
 | 
			
		||||
					throw new DataRetrievalFailureException(
 | 
			
		||||
							"Unable to map column " + column + " to property " + pd.getName(), ex);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) {
 | 
			
		||||
			throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields " +
 | 
			
		||||
					"necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return mappedObject;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize the given BeanWrapper to be used for row mapping.
 | 
			
		||||
	 * To be called for each row.
 | 
			
		||||
	 * <p>The default implementation is empty. Can be overridden in subclasses.
 | 
			
		||||
	 * @param bw the BeanWrapper to initialize
 | 
			
		||||
	 */
 | 
			
		||||
	protected void initBeanWrapper(BeanWrapper bw) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Retrieve a JDBC object value for the specified column.
 | 
			
		||||
	 * <p>The default implementation calls
 | 
			
		||||
	 * {@link JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class)}.
 | 
			
		||||
	 * Subclasses may override this to check specific value types upfront,
 | 
			
		||||
	 * or to post-process values return from <code>getResultSetValue</code>.
 | 
			
		||||
	 * @param rs is the ResultSet holding the data
 | 
			
		||||
	 * @param index is the column index
 | 
			
		||||
	 * @param pd the bean property that each result object is expected to match
 | 
			
		||||
	 * (or <code>null</code> if none specified)
 | 
			
		||||
	 * @return the Object value
 | 
			
		||||
	 * @throws SQLException in case of extraction failure
 | 
			
		||||
	 * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class)
 | 
			
		||||
	 */
 | 
			
		||||
	protected Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd) throws SQLException {
 | 
			
		||||
		return JdbcUtils.getResultSetValue(rs, index, pd.getPropertyType());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.CallableStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic callback interface for code that operates on a CallableStatement.
 | 
			
		||||
 * Allows to execute any number of operations on a single CallableStatement,
 | 
			
		||||
 * for example a single execute call or repeated execute calls with varying
 | 
			
		||||
 * parameters.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Used internally by JdbcTemplate, but also useful for application code.
 | 
			
		||||
 * Note that the passed-in CallableStatement can have been created by the
 | 
			
		||||
 * framework or by a custom CallableStatementCreator. However, the latter is
 | 
			
		||||
 * hardly ever necessary, as most custom callback actions will perform updates
 | 
			
		||||
 * in which case a standard CallableStatement is fine. Custom actions will
 | 
			
		||||
 * always set parameter values themselves, so that CallableStatementCreator
 | 
			
		||||
 * capability is not needed either.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 16.03.2004
 | 
			
		||||
 * @see JdbcTemplate#execute(String, CallableStatementCallback)
 | 
			
		||||
 * @see JdbcTemplate#execute(CallableStatementCreator, CallableStatementCallback)
 | 
			
		||||
 */
 | 
			
		||||
public interface CallableStatementCallback {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Gets called by <code>JdbcTemplate.execute</code> with an active JDBC
 | 
			
		||||
	 * CallableStatement. Does not need to care about closing the Statement
 | 
			
		||||
	 * or the Connection, or about handling transactions: this will all be
 | 
			
		||||
	 * handled by Spring's JdbcTemplate.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p><b>NOTE:</b> Any ResultSets opened should be closed in finally blocks
 | 
			
		||||
	 * within the callback implementation. Spring will close the Statement
 | 
			
		||||
	 * object after the callback returned, but this does not necessarily imply
 | 
			
		||||
	 * that the ResultSet resources will be closed: the Statement objects might
 | 
			
		||||
	 * get pooled by the connection pool, with <code>close</code> calls only
 | 
			
		||||
	 * returning the object to the pool but not physically closing the resources.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>If called without a thread-bound JDBC transaction (initiated by
 | 
			
		||||
	 * DataSourceTransactionManager), the code will simply get executed on the
 | 
			
		||||
	 * JDBC connection with its transactional semantics. If JdbcTemplate is
 | 
			
		||||
	 * configured to use a JTA-aware DataSource, the JDBC connection and thus
 | 
			
		||||
	 * the callback code will be transactional if a JTA transaction is active.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>Allows for returning a result object created within the callback, i.e.
 | 
			
		||||
	 * a domain object or a collection of domain objects. A thrown RuntimeException
 | 
			
		||||
	 * is treated as application exception: it gets propagated to the caller of
 | 
			
		||||
	 * the template.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param cs active JDBC CallableStatement
 | 
			
		||||
	 * @return a result object, or <code>null</code> if none
 | 
			
		||||
	 * @throws SQLException if thrown by a JDBC method, to be auto-converted
 | 
			
		||||
	 * into a DataAccessException by a SQLExceptionTranslator
 | 
			
		||||
	 * @throws DataAccessException in case of custom exceptions
 | 
			
		||||
	 */
 | 
			
		||||
	Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.CallableStatement;
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * One of the three central callback interfaces used by the JdbcTemplate class.
 | 
			
		||||
 * This interface creates a CallableStatement given a connection, provided
 | 
			
		||||
 * by the JdbcTemplate class. Implementations are responsible for providing
 | 
			
		||||
 * SQL and any necessary parameters.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Implementations <i>do not</i> need to concern themselves with
 | 
			
		||||
 * SQLExceptions that may be thrown from operations they attempt.
 | 
			
		||||
 * The JdbcTemplate class will catch and handle SQLExceptions appropriately.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A PreparedStatementCreator should also implement the SqlProvider interface
 | 
			
		||||
 * if it is able to provide the SQL it uses for PreparedStatement creation.
 | 
			
		||||
 * This allows for better contextual information in case of exceptions.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @see JdbcTemplate#execute(CallableStatementCreator, CallableStatementCallback)
 | 
			
		||||
 * @see JdbcTemplate#call
 | 
			
		||||
 * @see SqlProvider
 | 
			
		||||
 */
 | 
			
		||||
public interface CallableStatementCreator {
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Create a callable statement in this connection. Allows implementations to use
 | 
			
		||||
	 * CallableStatements. 
 | 
			
		||||
	 * @param con Connection to use to create statement
 | 
			
		||||
	 * @return a callable statement
 | 
			
		||||
	 * @throws SQLException there is no need to catch SQLExceptions
 | 
			
		||||
	 * that may be thrown in the implementation of this method.
 | 
			
		||||
	 * The JdbcTemplate class will handle them.
 | 
			
		||||
	 */
 | 
			
		||||
	CallableStatement createCallableStatement(Connection con) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,239 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.CallableStatement;
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper class that efficiently creates multiple {@link CallableStatementCreator}
 | 
			
		||||
 * objects with different parameters based on a SQL statement and a single
 | 
			
		||||
 * set of parameter declarations.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 */
 | 
			
		||||
public class CallableStatementCreatorFactory { 
 | 
			
		||||
 | 
			
		||||
	/** The SQL call string, which won't change when the parameters change. */
 | 
			
		||||
	private final String callString;
 | 
			
		||||
 | 
			
		||||
	/** List of SqlParameter objects. May not be <code>null</code>. */
 | 
			
		||||
	private final List declaredParameters;
 | 
			
		||||
 | 
			
		||||
	private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
 | 
			
		||||
 | 
			
		||||
	private boolean updatableResults = false;
 | 
			
		||||
 | 
			
		||||
	private NativeJdbcExtractor nativeJdbcExtractor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new factory. Will need to add parameters via the
 | 
			
		||||
	 * {@link #addParameter} method or have no parameters.
 | 
			
		||||
	 */
 | 
			
		||||
	public CallableStatementCreatorFactory(String callString) {
 | 
			
		||||
		this.callString = callString;
 | 
			
		||||
		this.declaredParameters = new LinkedList();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new factory with the given SQL and the given parameters.
 | 
			
		||||
	 * @param callString the SQL call string
 | 
			
		||||
	 * @param declaredParameters list of {@link SqlParameter} objects
 | 
			
		||||
	 */
 | 
			
		||||
	public CallableStatementCreatorFactory(String callString, List declaredParameters) {
 | 
			
		||||
		this.callString = callString;
 | 
			
		||||
		this.declaredParameters = declaredParameters;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a new declared parameter.
 | 
			
		||||
	 * <p>Order of parameter addition is significant.
 | 
			
		||||
	 * @param param the parameter to add to the list of declared parameters
 | 
			
		||||
	 */
 | 
			
		||||
	public void addParameter(SqlParameter param) {
 | 
			
		||||
		this.declaredParameters.add(param);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether to use prepared statements that return a specific type of ResultSet.
 | 
			
		||||
	 * specific type of ResultSet.
 | 
			
		||||
	 * @param resultSetType the ResultSet type
 | 
			
		||||
	 * @see java.sql.ResultSet#TYPE_FORWARD_ONLY
 | 
			
		||||
	 * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE
 | 
			
		||||
	 * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE
 | 
			
		||||
	 */
 | 
			
		||||
	public void setResultSetType(int resultSetType) {
 | 
			
		||||
		this.resultSetType = resultSetType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether to use prepared statements capable of returning updatable ResultSets.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setUpdatableResults(boolean updatableResults) {
 | 
			
		||||
		this.updatableResults = updatableResults;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the NativeJdbcExtractor to use for unwrapping CallableStatements, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
 | 
			
		||||
		this.nativeJdbcExtractor = nativeJdbcExtractor;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a new CallableStatementCreator instance given this parameters.
 | 
			
		||||
	 * @param params list of parameters (may be <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	public CallableStatementCreator newCallableStatementCreator(Map params) {
 | 
			
		||||
		return new CallableStatementCreatorImpl(params != null ? params : new HashMap());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a new CallableStatementCreator instance given this parameter mapper.
 | 
			
		||||
	 * @param inParamMapper ParameterMapper implementation that will return a Map of parameters
 | 
			
		||||
	 */
 | 
			
		||||
	public CallableStatementCreator newCallableStatementCreator(ParameterMapper inParamMapper) {
 | 
			
		||||
		return new CallableStatementCreatorImpl(inParamMapper);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * CallableStatementCreator implementation returned by this class.
 | 
			
		||||
	 */
 | 
			
		||||
	private class CallableStatementCreatorImpl implements CallableStatementCreator, SqlProvider, ParameterDisposer {
 | 
			
		||||
 | 
			
		||||
		private ParameterMapper inParameterMapper;
 | 
			
		||||
 | 
			
		||||
		private Map inParameters;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Create a new CallableStatementCreatorImpl.
 | 
			
		||||
		 * @param inParamMapper ParameterMapper implementation for mapping input parameters
 | 
			
		||||
		 */
 | 
			
		||||
		public CallableStatementCreatorImpl(ParameterMapper inParamMapper) {
 | 
			
		||||
			this.inParameterMapper = inParamMapper;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Create a new CallableStatementCreatorImpl.
 | 
			
		||||
		 * @param inParams list of SqlParameter objects
 | 
			
		||||
		 */
 | 
			
		||||
		public CallableStatementCreatorImpl(Map inParams) {
 | 
			
		||||
			this.inParameters = inParams;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public CallableStatement createCallableStatement(Connection con) throws SQLException {
 | 
			
		||||
			// If we were given a ParameterMapper, we must let the mapper do its thing to create the Map.
 | 
			
		||||
			if (this.inParameterMapper != null) {
 | 
			
		||||
				this.inParameters = this.inParameterMapper.createMap(con);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (this.inParameters == null) {
 | 
			
		||||
					throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
							"A ParameterMapper or a Map of parameters must be provided");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			CallableStatement cs = null;
 | 
			
		||||
			if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) {
 | 
			
		||||
				cs = con.prepareCall(callString);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				cs = con.prepareCall(callString, resultSetType,
 | 
			
		||||
						updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Determine CallabeStatement to pass to custom types.
 | 
			
		||||
			CallableStatement csToUse = cs;
 | 
			
		||||
			if (nativeJdbcExtractor != null) {
 | 
			
		||||
				csToUse = nativeJdbcExtractor.getNativeCallableStatement(cs);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			int sqlColIndx = 1;
 | 
			
		||||
			for (int i = 0; i < declaredParameters.size(); i++) {
 | 
			
		||||
				SqlParameter declaredParam = (SqlParameter) declaredParameters.get(i);
 | 
			
		||||
				if (!declaredParam.isResultsParameter()) {
 | 
			
		||||
					// So, it's a call parameter - part of the call string.
 | 
			
		||||
					// Get the value - it may still be null.
 | 
			
		||||
					Object inValue = this.inParameters.get(declaredParam.getName());
 | 
			
		||||
					if (declaredParam instanceof ResultSetSupportingSqlParameter) {
 | 
			
		||||
						// It's an output parameter: SqlReturnResultSet parameters already excluded.
 | 
			
		||||
						// It need not (but may be) supplied by the caller.
 | 
			
		||||
						if (declaredParam instanceof SqlOutParameter) {
 | 
			
		||||
							if (declaredParam.getTypeName() != null) {
 | 
			
		||||
								cs.registerOutParameter(sqlColIndx, declaredParam.getSqlType(), declaredParam.getTypeName());
 | 
			
		||||
							}
 | 
			
		||||
							else {
 | 
			
		||||
								if (declaredParam.getScale() != null) {
 | 
			
		||||
									cs.registerOutParameter(sqlColIndx, declaredParam.getSqlType(), declaredParam.getScale().intValue());
 | 
			
		||||
								}
 | 
			
		||||
								else {
 | 
			
		||||
									cs.registerOutParameter(sqlColIndx, declaredParam.getSqlType());
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
							if (declaredParam.isInputValueProvided()) {
 | 
			
		||||
								StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParam, inValue);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						// It's an input parameter; must be supplied by the caller.
 | 
			
		||||
						if (!this.inParameters.containsKey(declaredParam.getName())) {
 | 
			
		||||
							throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
									"Required input parameter '" + declaredParam.getName() + "' is missing");
 | 
			
		||||
						}
 | 
			
		||||
						StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParam, inValue);
 | 
			
		||||
					}
 | 
			
		||||
					sqlColIndx++;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return cs;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String getSql() {
 | 
			
		||||
			return callString;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void cleanupParameters() {
 | 
			
		||||
			if (this.inParameters != null) {
 | 
			
		||||
				StatementCreatorUtils.cleanupParameters(this.inParameters.values());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String toString() {
 | 
			
		||||
			StringBuffer buf = new StringBuffer("CallableStatementCreatorFactory.CallableStatementCreatorImpl: sql=[");
 | 
			
		||||
			buf.append(callString).append("]; parameters=").append(this.inParameters);
 | 
			
		||||
			return buf.toString();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.ResultSetMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.core.CollectionFactory;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link RowMapper} implementation that creates a <code>java.util.Map</code>
 | 
			
		||||
 * for each row, representing all columns as key-value pairs: one
 | 
			
		||||
 * entry for each column, with the column name as key.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The Map implementation to use and the key to use for each column
 | 
			
		||||
 * in the column Map can be customized through overriding
 | 
			
		||||
 * {@link #createColumnMap} and {@link #getColumnKey}, respectively.
 | 
			
		||||
 *
 | 
			
		||||
 * <p><b>Note:</b> By default, ColumnMapRowMapper will try to build a linked Map
 | 
			
		||||
 * with case-insensitive keys, to preserve column order as well as allow any
 | 
			
		||||
 * casing to be used for column names. This requires Commons Collections on the
 | 
			
		||||
 * classpath (which will be autodetected). Else, the fallback is a standard linked
 | 
			
		||||
 * HashMap, which will still preserve column order but requires the application
 | 
			
		||||
 * to specify the column names in the same casing as exposed by the driver.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.2
 | 
			
		||||
 * @see JdbcTemplate#queryForList(String)
 | 
			
		||||
 * @see JdbcTemplate#queryForMap(String)
 | 
			
		||||
 */
 | 
			
		||||
public class ColumnMapRowMapper implements RowMapper {
 | 
			
		||||
 | 
			
		||||
	public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
 | 
			
		||||
		ResultSetMetaData rsmd = rs.getMetaData();
 | 
			
		||||
		int columnCount = rsmd.getColumnCount();
 | 
			
		||||
		Map mapOfColValues = createColumnMap(columnCount);
 | 
			
		||||
		for (int i = 1; i <= columnCount; i++) {
 | 
			
		||||
			String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
 | 
			
		||||
			Object obj = getColumnValue(rs, i);
 | 
			
		||||
			mapOfColValues.put(key, obj);
 | 
			
		||||
		}
 | 
			
		||||
		return mapOfColValues;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a Map instance to be used as column map.
 | 
			
		||||
	 * <p>By default, a linked case-insensitive Map will be created if possible,
 | 
			
		||||
	 * else a plain HashMap (see Spring's CollectionFactory).
 | 
			
		||||
	 * @param columnCount the column count, to be used as initial
 | 
			
		||||
	 * capacity for the Map
 | 
			
		||||
	 * @return the new Map instance
 | 
			
		||||
	 * @see org.springframework.core.CollectionFactory#createLinkedCaseInsensitiveMapIfPossible
 | 
			
		||||
	 */
 | 
			
		||||
	protected Map createColumnMap(int columnCount) {
 | 
			
		||||
		return CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(columnCount);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Determine the key to use for the given column in the column Map.
 | 
			
		||||
	 * @param columnName the column name as returned by the ResultSet
 | 
			
		||||
	 * @return the column key to use
 | 
			
		||||
	 * @see java.sql.ResultSetMetaData#getColumnName
 | 
			
		||||
	 */
 | 
			
		||||
	protected String getColumnKey(String columnName) {
 | 
			
		||||
		return columnName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Retrieve a JDBC object value for the specified column.
 | 
			
		||||
	 * <p>The default implementation uses the <code>getObject</code> method.
 | 
			
		||||
	 * Additionally, this implementation includes a "hack" to get around Oracle
 | 
			
		||||
	 * returning a non standard object for their TIMESTAMP datatype.
 | 
			
		||||
	 * @param rs is the ResultSet holding the data
 | 
			
		||||
	 * @param index is the column index
 | 
			
		||||
	 * @return the Object returned
 | 
			
		||||
	 * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue
 | 
			
		||||
	 */
 | 
			
		||||
	protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
 | 
			
		||||
		return JdbcUtils.getResultSetValue(rs, index);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic callback interface for code that operates on a JDBC Connection.
 | 
			
		||||
 * Allows to execute any number of operations on a single Connection,
 | 
			
		||||
 * using any type and number of Statements.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This is particularly useful for delegating to existing data access code
 | 
			
		||||
 * that expects a Connection to work on and throws SQLException. For newly
 | 
			
		||||
 * written code, it is strongly recommended to use JdbcTemplate's more specific
 | 
			
		||||
 * operations, for example a <code>query</code> or <code>update</code> variant.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1.3
 | 
			
		||||
 * @see JdbcTemplate#execute(ConnectionCallback)
 | 
			
		||||
 * @see JdbcTemplate#query
 | 
			
		||||
 * @see JdbcTemplate#update
 | 
			
		||||
 */
 | 
			
		||||
public interface ConnectionCallback {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Gets called by <code>JdbcTemplate.execute</code> with an active JDBC
 | 
			
		||||
	 * Connection. Does not need to care about activating or closing the
 | 
			
		||||
	 * Connection, or handling transactions.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>If called without a thread-bound JDBC transaction (initiated by
 | 
			
		||||
	 * DataSourceTransactionManager), the code will simply get executed on the
 | 
			
		||||
	 * JDBC connection with its transactional semantics. If JdbcTemplate is
 | 
			
		||||
	 * configured to use a JTA-aware DataSource, the JDBC Connection and thus
 | 
			
		||||
	 * the callback code will be transactional if a JTA transaction is active.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>Allows for returning a result object created within the callback, i.e.
 | 
			
		||||
	 * a domain object or a collection of domain objects. Note that there's special
 | 
			
		||||
	 * support for single step actions: see <code>JdbcTemplate.queryForObject</code>
 | 
			
		||||
	 * etc. A thrown RuntimeException is treated as application exception:
 | 
			
		||||
	 * it gets propagated to the caller of the template.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param con active JDBC Connection
 | 
			
		||||
	 * @return a result object, or <code>null</code> if none
 | 
			
		||||
	 * @throws SQLException if thrown by a JDBC method, to be auto-converted
 | 
			
		||||
	 * to a DataAccessException by a SQLExceptionTranslator
 | 
			
		||||
	 * @throws DataAccessException in case of custom exceptions
 | 
			
		||||
	 * @see JdbcTemplate#queryForObject(String, Class)
 | 
			
		||||
	 * @see JdbcTemplate#queryForRowSet(String)
 | 
			
		||||
	 */
 | 
			
		||||
	Object doInConnection(Connection con) throws SQLException, DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subinterface of {@link SqlTypeValue} that adds a cleanup callback,
 | 
			
		||||
 * to be invoked after the value has been set and the corresponding
 | 
			
		||||
 * statement has been executed.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see org.springframework.jdbc.core.support.SqlLobValue
 | 
			
		||||
 */
 | 
			
		||||
public interface DisposableSqlTypeValue extends SqlTypeValue {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Clean up resources held by this type value,
 | 
			
		||||
	 * for example the LobCreator in case of a SqlLobValue.
 | 
			
		||||
	 * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup()
 | 
			
		||||
	 * @see org.springframework.jdbc.support.SqlValue#cleanup()
 | 
			
		||||
	 */
 | 
			
		||||
	void cleanup();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of the {@link BatchPreparedStatementSetter} interface,
 | 
			
		||||
 * adding a batch exhaustion check.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This interface allows you to signal the end of a batch rather than
 | 
			
		||||
 * having to determine the exact batch size upfront. Batch size is still
 | 
			
		||||
 * being honored but it is now the maximum size of the batch.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The {@link #isBatchExhausted} method is called after each call to
 | 
			
		||||
 * {@link #setValues} to determine whether there were some values added,
 | 
			
		||||
 * or if the batch was determined to be complete and no additional values
 | 
			
		||||
 * were provided during the last call to <code>setValues</code>.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Consider extending the
 | 
			
		||||
 * {@link org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter}
 | 
			
		||||
 * base class instead of implementing this interface directly, using a single
 | 
			
		||||
 * <code>setValuesIfAvailable</code> callback method that checks for available
 | 
			
		||||
 * values and sets them, returning whether values have actually been provided.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see JdbcTemplate#batchUpdate(String, BatchPreparedStatementSetter)
 | 
			
		||||
 * @see org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter
 | 
			
		||||
 */
 | 
			
		||||
public interface InterruptibleBatchPreparedStatementSetter extends BatchPreparedStatementSetter {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether the batch is complete, that is, whether there were no
 | 
			
		||||
	 * additional values added during the last <code>setValues</code> call.
 | 
			
		||||
	 * <p><b>NOTE:</b> If this method returns <code>true</code>, any parameters
 | 
			
		||||
	 * that might have been set during the last <code>setValues</code> call will
 | 
			
		||||
	 * be ignored! Make sure that you set a corresponding internal flag if you
 | 
			
		||||
	 * detect exhaustion <i>at the beginning</i> of your <code>setValues</code>
 | 
			
		||||
	 * implementation, letting this method return <code>true</code> based on the flag.
 | 
			
		||||
	 * @param i index of the statement we're issuing in the batch, starting from 0
 | 
			
		||||
	 * @return whether the batch is already exhausted
 | 
			
		||||
	 * @see #setValues
 | 
			
		||||
	 * @see org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter#setValuesIfAvailable
 | 
			
		||||
	 */
 | 
			
		||||
	boolean isBatchExhausted(int i);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,936 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
 | 
			
		||||
import org.springframework.jdbc.support.KeyHolder;
 | 
			
		||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface specifying a basic set of JDBC operations.
 | 
			
		||||
 * Implemented by {@link JdbcTemplate}. Not often used directly, but a useful
 | 
			
		||||
 * option to enhance testability, as it can easily be mocked or stubbed.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Alternatively, the standard JDBC infrastructure can be mocked.
 | 
			
		||||
 * However, mocking this interface constitutes significantly less work.
 | 
			
		||||
 * As an alternative to a mock objects approach to testing data access code,
 | 
			
		||||
 * consider the powerful integration testing support provided in the
 | 
			
		||||
 * <code>org.springframework.test</code> package, shipped in
 | 
			
		||||
 * <code>spring-mock.jar</code>.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @see JdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public interface JdbcOperations {
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods dealing with a plain java.sql.Connection
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC Connection. This allows for implementing arbitrary
 | 
			
		||||
	 * data access operations, within Spring's managed JDBC environment:
 | 
			
		||||
	 * that is, participating in Spring-managed transactions and converting
 | 
			
		||||
	 * JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param action the callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(ConnectionCallback action) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods dealing with static SQL (java.sql.Statement)
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC Statement. This allows for implementing arbitrary data
 | 
			
		||||
	 * access operations on a single Statement, within Spring's managed JDBC
 | 
			
		||||
	 * environment: that is, participating in Spring-managed transactions and
 | 
			
		||||
	 * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param action callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(StatementCallback action) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue a single SQL execute, typically a DDL statement.
 | 
			
		||||
	 * @param sql static SQL to execute
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	void execute(String sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query given static SQL, reading the ResultSet with a
 | 
			
		||||
	 * ResultSetExtractor.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>query</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param rse object that will extract all rows of results
 | 
			
		||||
	 * @return an arbitrary result object, as returned by the ResultSetExtractor
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #query(String, Object[], ResultSetExtractor)
 | 
			
		||||
	 */
 | 
			
		||||
	Object query(String sql, ResultSetExtractor rse) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query given static SQL, reading the ResultSet on a per-row
 | 
			
		||||
	 * basis with a RowCallbackHandler.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>query</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param rch object that will extract results, one row at a time
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #query(String, Object[], RowCallbackHandler)
 | 
			
		||||
	 */
 | 
			
		||||
	void query(String sql, RowCallbackHandler rch) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query given static SQL, mapping each row to a Java object
 | 
			
		||||
	 * via a RowMapper.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>query</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the result List, containing mapped objects
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #query(String, Object[], RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	List query(String sql, RowMapper rowMapper) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query given static SQL, mapping a single result row to a Java
 | 
			
		||||
	 * object via a RowMapper.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForObject</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the single mapped object
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not
 | 
			
		||||
	 * return exactly one row
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForObject(String, Object[], RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, RowMapper rowMapper) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query for a result object, given static SQL.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForObject</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * <p>This method is useful for running static SQL with a known outcome.
 | 
			
		||||
	 * The query is expected to be a single row/single column query; the returned
 | 
			
		||||
	 * result will be directly mapped to the corresponding object type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param requiredType the type that the result object is expected to match
 | 
			
		||||
	 * @return the result object of the required type, or <code>null</code> in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForObject(String, Object[], Class)
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, Class requiredType) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query for a result Map, given static SQL.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForMap</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @return the result Map (one entry for each column, using the
 | 
			
		||||
	 * column name as the key)
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not
 | 
			
		||||
	 * return exactly one row
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForMap(String, Object[])
 | 
			
		||||
	 * @see ColumnMapRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	Map queryForMap(String sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query that results in a long value, given static SQL.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForLong</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * <p>This method is useful for running static SQL with a known outcome.
 | 
			
		||||
	 * The query is expected to be a single row/single column query that results
 | 
			
		||||
	 * in a long value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @return the long value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForLong(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query that results in an int value, given static SQL.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForInt</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * <p>This method is useful for running static SQL with a known outcome.
 | 
			
		||||
	 * The query is expected to be a single row/single column query that results
 | 
			
		||||
	 * in an int value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @return the int value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForInt(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query for a result list, given static SQL.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForList</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * result objects, each of them matching the specified element type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param elementType the required type of element in the result list
 | 
			
		||||
	 * (for example, <code>Integer.class</code>)
 | 
			
		||||
	 * @return a List of objects that match the specified element type
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForList(String, Object[], Class)
 | 
			
		||||
	 * @see SingleColumnRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, Class elementType) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query for a result list, given static SQL.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForList</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * Maps (one entry for each column using the column name as the key).
 | 
			
		||||
	 * Each element in the list will be of the form returned by this interface's
 | 
			
		||||
	 * queryForMap() methods.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @return an List that contains a Map per row
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForList(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a query for a SqlRowSet, given static SQL.
 | 
			
		||||
	 * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
 | 
			
		||||
	 * execute a static query with a PreparedStatement, use the overloaded
 | 
			
		||||
	 * <code>queryForRowSet</code> method with <code>null</code> as argument array.
 | 
			
		||||
	 * <p>The results will be mapped to an SqlRowSet which holds the data in a
 | 
			
		||||
	 * disconnected fashion. This wrapper will translate any SQLExceptions thrown.
 | 
			
		||||
	 * <p>Note that that, for the default implementation, JDBC RowSet support needs to
 | 
			
		||||
	 * be available at runtime: by default, Sun's <code>com.sun.rowset.CachedRowSetImpl</code>
 | 
			
		||||
	 * class is used, which is part of JDK 1.5+ and also available separately as part of
 | 
			
		||||
	 * Sun's JDBC RowSet Implementations download (rowset.jar).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @return a SqlRowSet representation (possibly a wrapper around a
 | 
			
		||||
	 * <code>javax.sql.rowset.CachedRowSet</code>)
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForRowSet(String, Object[])
 | 
			
		||||
	 * @see SqlRowSetResultSetExtractor
 | 
			
		||||
	 * @see javax.sql.rowset.CachedRowSet
 | 
			
		||||
	 */
 | 
			
		||||
	SqlRowSet queryForRowSet(String sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue a single SQL update operation (such as an insert, update or delete statement).
 | 
			
		||||
	 * @param sql static SQL to execute
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws DataAccessException if there is any problem.
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue multiple SQL updates on a single JDBC Statement using batching.
 | 
			
		||||
	 * <p>Will fall back to separate updates on a single Statement if the JDBC
 | 
			
		||||
	 * driver does not support batch updates.
 | 
			
		||||
	 * @param sql defining an array of SQL statements that will be executed.
 | 
			
		||||
	 * @return an array of the number of rows affected by each statement
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the batch
 | 
			
		||||
	 */
 | 
			
		||||
	int[] batchUpdate(String[] sql) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods dealing with prepared statements
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC PreparedStatement. This allows for implementing arbitrary
 | 
			
		||||
	 * data access operations on a single Statement, within Spring's managed
 | 
			
		||||
	 * JDBC environment: that is, participating in Spring-managed transactions
 | 
			
		||||
	 * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param psc object that can create a PreparedStatement given a Connection
 | 
			
		||||
	 * @param action callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(PreparedStatementCreator psc, PreparedStatementCallback action)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC PreparedStatement. This allows for implementing arbitrary
 | 
			
		||||
	 * data access operations on a single Statement, within Spring's managed
 | 
			
		||||
	 * JDBC environment: that is, participating in Spring-managed transactions
 | 
			
		||||
	 * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param sql SQL to execute
 | 
			
		||||
	 * @param action callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(String sql, PreparedStatementCallback action) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query using a prepared statement, reading the ResultSet with a
 | 
			
		||||
	 * ResultSetExtractor.
 | 
			
		||||
	 * <p>A PreparedStatementCreator can either be implemented directly or
 | 
			
		||||
	 * configured through a PreparedStatementCreatorFactory.
 | 
			
		||||
	 * @param psc object that can create a PreparedStatement given a Connection
 | 
			
		||||
	 * @param rse object that will extract results
 | 
			
		||||
	 * @return an arbitrary result object, as returned by the ResultSetExtractor
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 * @see PreparedStatementCreatorFactory
 | 
			
		||||
	 */
 | 
			
		||||
	Object query(PreparedStatementCreator psc, ResultSetExtractor rse) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query using a prepared statement, reading the ResultSet with a
 | 
			
		||||
	 * ResultSetExtractor.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param pss object that knows how to set values on the prepared statement.
 | 
			
		||||
	 * If this is <code>null</code>, the SQL will be assumed to contain no bind parameters.
 | 
			
		||||
	 * Even if there are no bind parameters, this object may be used to
 | 
			
		||||
	 * set fetch size and other performance options.
 | 
			
		||||
	 * @param rse object that will extract results
 | 
			
		||||
	 * @return an arbitrary result object, as returned by the ResultSetExtractor
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object query(String sql, PreparedStatementSetter pss, ResultSetExtractor rse)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, reading the ResultSet with a
 | 
			
		||||
	 * ResultSetExtractor.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @param rse object that will extract results
 | 
			
		||||
	 * @return an arbitrary result object, as returned by the ResultSetExtractor
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	Object query(String sql, Object[] args, int[] argTypes, ResultSetExtractor rse)
 | 
			
		||||
	    throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, reading the ResultSet with a
 | 
			
		||||
	 * ResultSetExtractor.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @param rse object that will extract results
 | 
			
		||||
	 * @return an arbitrary result object, as returned by the ResultSetExtractor
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	Object query(String sql, Object[] args, ResultSetExtractor rse) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query using a prepared statement, reading the ResultSet on a per-row
 | 
			
		||||
	 * basis with a RowCallbackHandler.
 | 
			
		||||
	 * <p>A PreparedStatementCreator can either be implemented directly or
 | 
			
		||||
	 * configured through a PreparedStatementCreatorFactory.
 | 
			
		||||
	 * @param psc object that can create a PreparedStatement given a Connection
 | 
			
		||||
	 * @param rch object that will extract results, one row at a time
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 * @see PreparedStatementCreatorFactory
 | 
			
		||||
	 */
 | 
			
		||||
	void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * PreparedStatementSetter implementation that knows how to bind values
 | 
			
		||||
	 * to the query, reading the ResultSet on a per-row basis with a
 | 
			
		||||
	 * RowCallbackHandler.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param pss object that knows how to set values on the prepared statement.
 | 
			
		||||
	 * If this is <code>null</code>, the SQL will be assumed to contain no bind parameters.
 | 
			
		||||
	 * Even if there are no bind parameters, this object may be used to
 | 
			
		||||
	 * set fetch size and other performance options.
 | 
			
		||||
	 * @param rch object that will extract results, one row at a time
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	void query(String sql, PreparedStatementSetter pss, RowCallbackHandler rch)
 | 
			
		||||
	    throws DataAccessException;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list of
 | 
			
		||||
	 * arguments to bind to the query, reading the ResultSet on a per-row basis
 | 
			
		||||
	 * with a RowCallbackHandler.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @param rch object that will extract results, one row at a time
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch)
 | 
			
		||||
	    throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list of
 | 
			
		||||
	 * arguments to bind to the query, reading the ResultSet on a per-row basis
 | 
			
		||||
	 * with a RowCallbackHandler.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @param rch object that will extract results, one row at a time
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	void query(String sql, Object[] args, RowCallbackHandler rch) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query using a prepared statement, mapping each row to a Java object
 | 
			
		||||
	 * via a RowMapper.
 | 
			
		||||
	 * <p>A PreparedStatementCreator can either be implemented directly or
 | 
			
		||||
	 * configured through a PreparedStatementCreatorFactory.
 | 
			
		||||
	 * @param psc object that can create a PreparedStatement given a Connection
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the result List, containing mapped objects
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 * @see PreparedStatementCreatorFactory
 | 
			
		||||
	 */
 | 
			
		||||
	List query(PreparedStatementCreator psc, RowMapper rowMapper) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * PreparedStatementSetter implementation that knows how to bind values
 | 
			
		||||
	 * to the query, mapping each row to a Java object via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param pss object that knows how to set values on the prepared statement.
 | 
			
		||||
	 * If this is <code>null</code>, the SQL will be assumed to contain no bind parameters.
 | 
			
		||||
	 * Even if there are no bind parameters, this object may be used to
 | 
			
		||||
	 * set fetch size and other performance options.
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the result List, containing mapped objects
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	List query(String sql, PreparedStatementSetter pss, RowMapper rowMapper)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping each row to a Java object
 | 
			
		||||
	 * via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the result List, containing mapped objects
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	List query(String sql, Object[] args, int[] argTypes, RowMapper rowMapper)
 | 
			
		||||
	    throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping each row to a Java object
 | 
			
		||||
	 * via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the result List, containing mapped objects
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	List query(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping a single result row to a
 | 
			
		||||
	 * Java object via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the single mapped object
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not
 | 
			
		||||
	 * return exactly one row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping a single result row to a
 | 
			
		||||
	 * Java object via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the single mapped object
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not
 | 
			
		||||
	 * return exactly one row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, Object[] args, RowMapper rowMapper)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result object.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query; the returned
 | 
			
		||||
	 * result will be directly mapped to the corresponding object type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @param requiredType the type that the result object is expected to match
 | 
			
		||||
	 * @return the result object of the required type, or <code>null</code> in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForObject(String, Class)
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, Object[] args, int[] argTypes, Class requiredType)
 | 
			
		||||
	    throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result object.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query; the returned
 | 
			
		||||
	 * result will be directly mapped to the corresponding object type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @param requiredType the type that the result object is expected to match
 | 
			
		||||
	 * @return the result object of the required type, or <code>null</code> in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForObject(String, Class)
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, Object[] args, Class requiredType) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result Map.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @return the result Map (one entry for each column, using the
 | 
			
		||||
	 * column name as the key)
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not
 | 
			
		||||
	 * return exactly one row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForMap(String)
 | 
			
		||||
	 * @see ColumnMapRowMapper
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	Map queryForMap(String sql, Object[] args, int[] argTypes) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result Map.
 | 
			
		||||
	 * The queryForMap() methods defined by this interface are appropriate
 | 
			
		||||
	 * when you don't have a domain model. Otherwise, consider using
 | 
			
		||||
	 * one of the queryForObject() methods.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @return the result Map (one entry for each column, using the
 | 
			
		||||
	 * column name as the key)
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not
 | 
			
		||||
	 * return exactly one row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForMap(String)
 | 
			
		||||
	 * @see ColumnMapRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	Map queryForMap(String sql, Object[] args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in a long value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in a long value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @return the long value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForLong(String)
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql, Object[] args, int[] argTypes) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in a long value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in a long value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @return the long value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForLong(String)
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql, Object[] args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in an int value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in an int value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @return the int value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForInt(String)
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql, Object[] args, int[] argTypes) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in an int value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in an int value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @return the int value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForInt(String)
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql, Object[] args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * result objects, each of them matching the specified element type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @param elementType the required type of element in the result list
 | 
			
		||||
	 * (for example, <code>Integer.class</code>)
 | 
			
		||||
	 * @return a List of objects that match the specified element type
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForList(String, Class)
 | 
			
		||||
	 * @see SingleColumnRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, Object[] args, int[] argTypes, Class elementType)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * result objects, each of them matching the specified element type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @param elementType the required type of element in the result list
 | 
			
		||||
	 * (for example, <code>Integer.class</code>)
 | 
			
		||||
	 * @return a List of objects that match the specified element type
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForList(String, Class)
 | 
			
		||||
	 * @see SingleColumnRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, Object[] args, Class elementType) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * Maps (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * Thus  Each element in the list will be of the form returned by this interface's
 | 
			
		||||
	 * queryForMap() methods.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @return a List that contains a Map per row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForList(String)
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, Object[] args, int[] argTypes) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * Maps (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * Each element in the list will be of the form returned by this interface's
 | 
			
		||||
	 * queryForMap() methods.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @return a List that contains a Map per row
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 * @see #queryForList(String)
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, Object[] args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a SqlRowSet.
 | 
			
		||||
	 * <p>The results will be mapped to an SqlRowSet which holds the data in a
 | 
			
		||||
	 * disconnected fashion. This wrapper will translate any SQLExceptions thrown.
 | 
			
		||||
	 * <p>Note that that, for the default implementation, JDBC RowSet support needs to
 | 
			
		||||
	 * be available at runtime: by default, Sun's <code>com.sun.rowset.CachedRowSetImpl</code>
 | 
			
		||||
	 * class is used, which is part of JDK 1.5+ and also available separately as part of
 | 
			
		||||
	 * Sun's JDBC RowSet Implementations download (rowset.jar).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @return a SqlRowSet representation (possibly a wrapper around a
 | 
			
		||||
	 * <code>javax.sql.rowset.CachedRowSet</code>)
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForRowSet(String)
 | 
			
		||||
	 * @see SqlRowSetResultSetExtractor
 | 
			
		||||
	 * @see javax.sql.rowset.CachedRowSet
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a SqlRowSet.
 | 
			
		||||
	 * <p>The results will be mapped to an SqlRowSet which holds the data in a
 | 
			
		||||
	 * disconnected fashion. This wrapper will translate any SQLExceptions thrown.
 | 
			
		||||
	 * <p>Note that that, for the default implementation, JDBC RowSet support needs to
 | 
			
		||||
	 * be available at runtime: by default, Sun's <code>com.sun.rowset.CachedRowSetImpl</code>
 | 
			
		||||
	 * class is used, which is part of JDK 1.5+ and also available separately as part of
 | 
			
		||||
	 * Sun's JDBC RowSet Implementations download (rowset.jar).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @return a SqlRowSet representation (possibly a wrapper around a
 | 
			
		||||
	 * <code>javax.sql.rowset.CachedRowSet</code>)
 | 
			
		||||
	 * @throws DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see #queryForRowSet(String)
 | 
			
		||||
	 * @see SqlRowSetResultSetExtractor
 | 
			
		||||
	 * @see javax.sql.rowset.CachedRowSet
 | 
			
		||||
	 */
 | 
			
		||||
	SqlRowSet queryForRowSet(String sql, Object[] args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue a single SQL update operation (such as an insert, update or delete statement)
 | 
			
		||||
	 * using a PreparedStatementCreator to provide SQL and any required parameters.
 | 
			
		||||
	 * <p>A PreparedStatementCreator can either be implemented directly or
 | 
			
		||||
	 * configured through a PreparedStatementCreatorFactory.
 | 
			
		||||
	 * @param psc object that provides SQL and any necessary parameters
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 * @see PreparedStatementCreatorFactory
 | 
			
		||||
	 */
 | 
			
		||||
	int update(PreparedStatementCreator psc) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue an update statement using a PreparedStatementCreator to provide SQL and
 | 
			
		||||
	 * any required parameters. Generated keys will be put into the given KeyHolder.
 | 
			
		||||
	 * <p>Note that the given PreparedStatementCreator has to create a statement
 | 
			
		||||
	 * with activated extraction of generated keys (a JDBC 3.0 feature). This can
 | 
			
		||||
	 * either be done directly or through using a PreparedStatementCreatorFactory.
 | 
			
		||||
	 * @param psc object that provides SQL and any necessary parameters
 | 
			
		||||
	 * @param generatedKeyHolder KeyHolder that will hold the generated keys
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 * @see PreparedStatementCreatorFactory
 | 
			
		||||
	 * @see org.springframework.jdbc.support.GeneratedKeyHolder
 | 
			
		||||
	 */
 | 
			
		||||
	int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue an update statement using a PreparedStatementSetter to set bind parameters,
 | 
			
		||||
	 * with given SQL. Simpler than using a PreparedStatementCreator as this method
 | 
			
		||||
	 * will create the PreparedStatement: The PreparedStatementSetter just needs to
 | 
			
		||||
	 * set parameters.
 | 
			
		||||
	 * @param sql SQL containing bind parameters
 | 
			
		||||
	 * @param pss helper that sets bind parameters. If this is <code>null</code>
 | 
			
		||||
	 * we run an update with static SQL.
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, PreparedStatementSetter pss) throws DataAccessException;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue a single SQL update operation (such as an insert, update or delete statement)
 | 
			
		||||
	 * via a prepared statement, binding the given arguments.
 | 
			
		||||
	 * @param sql SQL containing bind parameters
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, Object[] args, int[] argTypes) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue a single SQL update operation (such as an insert, update or delete statement)
 | 
			
		||||
	 * via a prepared statement, binding the given arguments.
 | 
			
		||||
	 * @param sql SQL containing bind parameters
 | 
			
		||||
	 * @param args arguments to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type);
 | 
			
		||||
	 * may also contain {@link SqlParameterValue} objects which indicate not
 | 
			
		||||
	 * only the argument value but also the SQL type and optionally the scale
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, Object[] args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue multiple update statements on a single PreparedStatement,
 | 
			
		||||
	 * using batch updates and a BatchPreparedStatementSetter to set values.
 | 
			
		||||
	 * <p>Will fall back to separate updates on a single PreparedStatement
 | 
			
		||||
	 * if the JDBC driver does not support batch updates.
 | 
			
		||||
	 * @param sql defining PreparedStatement that will be reused.
 | 
			
		||||
	 * All statements in the batch will use the same SQL.
 | 
			
		||||
	 * @param pss object to set parameters on the PreparedStatement
 | 
			
		||||
	 * created by this method
 | 
			
		||||
	 * @return an array of the number of rows affected by each statement
 | 
			
		||||
	 * @throws DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 */
 | 
			
		||||
	int[] batchUpdate(String sql, BatchPreparedStatementSetter pss) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods dealing with callable statements
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC CallableStatement. This allows for implementing arbitrary
 | 
			
		||||
	 * data access operations on a single Statement, within Spring's managed
 | 
			
		||||
	 * JDBC environment: that is, participating in Spring-managed transactions
 | 
			
		||||
	 * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param csc object that can create a CallableStatement given a Connection
 | 
			
		||||
	 * @param action callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(CallableStatementCreator csc, CallableStatementCallback action)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC CallableStatement. This allows for implementing arbitrary
 | 
			
		||||
	 * data access operations on a single Statement, within Spring's managed
 | 
			
		||||
	 * JDBC environment: that is, participating in Spring-managed transactions
 | 
			
		||||
	 * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param callString the SQL call string to execute
 | 
			
		||||
	 * @param action callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(String callString, CallableStatementCallback action) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a SQL call using a CallableStatementCreator to provide SQL and any
 | 
			
		||||
	 * required parameters.
 | 
			
		||||
	 * @param csc object that provides SQL and any necessary parameters
 | 
			
		||||
	 * @param declaredParameters list of declared SqlParameter objects
 | 
			
		||||
	 * @return Map of extracted out parameters
 | 
			
		||||
	 * @throws DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 */
 | 
			
		||||
	Map call(CallableStatementCreator csc, List declaredParameters) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface to be implemented by objects that can close resources
 | 
			
		||||
 * allocated by parameters like SqlLobValues.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Typically implemented by PreparedStatementCreators and
 | 
			
		||||
 * PreparedStatementSetters that support DisposableSqlTypeValue
 | 
			
		||||
 * objects (e.g. SqlLobValue) as parameters.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see PreparedStatementCreator
 | 
			
		||||
 * @see PreparedStatementSetter
 | 
			
		||||
 * @see DisposableSqlTypeValue
 | 
			
		||||
 * @see org.springframework.jdbc.core.support.SqlLobValue
 | 
			
		||||
 */
 | 
			
		||||
public interface ParameterDisposer {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Close the resources allocated by parameters that the implementing
 | 
			
		||||
	 * object holds, for example in case of a DisposableSqlTypeValue
 | 
			
		||||
	 * (like a SqlLobValue).
 | 
			
		||||
	 * @see DisposableSqlTypeValue#cleanup
 | 
			
		||||
	 * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup
 | 
			
		||||
	 */
 | 
			
		||||
	public void cleanupParameters();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,47 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Implement this interface when parameters need to be customized based
 | 
			
		||||
 * on the connection. We might need to do this to make use of proprietary
 | 
			
		||||
 * features, available only with a specific Connection type.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @see CallableStatementCreatorFactory#newCallableStatementCreator(ParameterMapper)
 | 
			
		||||
 * @see org.springframework.jdbc.object.StoredProcedure#execute(ParameterMapper)
 | 
			
		||||
 */
 | 
			
		||||
public interface ParameterMapper {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a Map of input parameters, keyed by name.
 | 
			
		||||
	 * @param con JDBC connection. This is useful (and the purpose of this interface)
 | 
			
		||||
	 * if we need to do something RDBMS-specific with a proprietary Connection
 | 
			
		||||
	 * implementation class. This class conceals such proprietary details. However,
 | 
			
		||||
	 * it is best to avoid using such proprietary RDBMS features if possible.
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered setting
 | 
			
		||||
	 * parameter values (that is, there's no need to catch SQLException)
 | 
			
		||||
	 * @return Map of input parameters, keyed by name (never <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	Map createMap(Connection con) throws SQLException;
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic callback interface for code that operates on a PreparedStatement.
 | 
			
		||||
 * Allows to execute any number of operations on a single PreparedStatement,
 | 
			
		||||
 * for example a single <code>executeUpdate</code> call or repeated
 | 
			
		||||
 * <code>executeUpdate</code> calls with varying parameters.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Used internally by JdbcTemplate, but also useful for application code.
 | 
			
		||||
 * Note that the passed-in PreparedStatement can have been created by the
 | 
			
		||||
 * framework or by a custom PreparedStatementCreator. However, the latter is
 | 
			
		||||
 * hardly ever necessary, as most custom callback actions will perform updates
 | 
			
		||||
 * in which case a standard PreparedStatement is fine. Custom actions will
 | 
			
		||||
 * always set parameter values themselves, so that PreparedStatementCreator
 | 
			
		||||
 * capability is not needed either.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 16.03.2004
 | 
			
		||||
 * @see JdbcTemplate#execute(String, PreparedStatementCallback)
 | 
			
		||||
 * @see JdbcTemplate#execute(PreparedStatementCreator, PreparedStatementCallback)
 | 
			
		||||
 */
 | 
			
		||||
public interface PreparedStatementCallback {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Gets called by <code>JdbcTemplate.execute</code> with an active JDBC
 | 
			
		||||
	 * PreparedStatement. Does not need to care about closing the Statement
 | 
			
		||||
	 * or the Connection, or about handling transactions: this will all be
 | 
			
		||||
	 * handled by Spring's JdbcTemplate.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p><b>NOTE:</b> Any ResultSets opened should be closed in finally blocks
 | 
			
		||||
	 * within the callback implementation. Spring will close the Statement
 | 
			
		||||
	 * object after the callback returned, but this does not necessarily imply
 | 
			
		||||
	 * that the ResultSet resources will be closed: the Statement objects might
 | 
			
		||||
	 * get pooled by the connection pool, with <code>close</code> calls only
 | 
			
		||||
	 * returning the object to the pool but not physically closing the resources.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>If called without a thread-bound JDBC transaction (initiated by
 | 
			
		||||
	 * DataSourceTransactionManager), the code will simply get executed on the
 | 
			
		||||
	 * JDBC connection with its transactional semantics. If JdbcTemplate is
 | 
			
		||||
	 * configured to use a JTA-aware DataSource, the JDBC connection and thus
 | 
			
		||||
	 * the callback code will be transactional if a JTA transaction is active.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>Allows for returning a result object created within the callback, i.e.
 | 
			
		||||
	 * a domain object or a collection of domain objects. Note that there's
 | 
			
		||||
	 * special support for single step actions: see JdbcTemplate.queryForObject etc.
 | 
			
		||||
	 * A thrown RuntimeException is treated as application exception, it gets
 | 
			
		||||
	 * propagated to the caller of the template.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ps active JDBC PreparedStatement
 | 
			
		||||
	 * @return a result object, or <code>null</code> if none
 | 
			
		||||
	 * @throws SQLException if thrown by a JDBC method, to be auto-converted
 | 
			
		||||
	 * to a DataAccessException by a SQLExceptionTranslator
 | 
			
		||||
	 * @throws DataAccessException in case of custom exceptions
 | 
			
		||||
	 * @see JdbcTemplate#queryForObject(String, Object[], Class)
 | 
			
		||||
	 * @see JdbcTemplate#queryForList(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * One of the two central callback interfaces used by the JdbcTemplate class.
 | 
			
		||||
 * This interface creates a PreparedStatement given a connection, provided
 | 
			
		||||
 * by the JdbcTemplate class. Implementations are responsible for providing
 | 
			
		||||
 * SQL and any necessary parameters.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Implementations <i>do not</i> need to concern themselves with
 | 
			
		||||
 * SQLExceptions that may be thrown from operations they attempt.
 | 
			
		||||
 * The JdbcTemplate class will catch and handle SQLExceptions appropriately.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A PreparedStatementCreator should also implement the SqlProvider interface
 | 
			
		||||
 * if it is able to provide the SQL it uses for PreparedStatement creation.
 | 
			
		||||
 * This allows for better contextual information in case of exceptions.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @see JdbcTemplate#execute(PreparedStatementCreator, PreparedStatementCallback)
 | 
			
		||||
 * @see JdbcTemplate#query(PreparedStatementCreator, RowCallbackHandler)
 | 
			
		||||
 * @see JdbcTemplate#update(PreparedStatementCreator)
 | 
			
		||||
 * @see SqlProvider
 | 
			
		||||
 */
 | 
			
		||||
public interface PreparedStatementCreator {
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Create a statement in this connection. Allows implementations to use
 | 
			
		||||
	 * PreparedStatements. The JdbcTemplate will close the created statement.
 | 
			
		||||
	 * @param con Connection to use to create statement
 | 
			
		||||
	 * @return a prepared statement
 | 
			
		||||
	 * @throws SQLException there is no need to catch SQLExceptions
 | 
			
		||||
	 * that may be thrown in the implementation of this method.
 | 
			
		||||
	 * The JdbcTemplate class will handle them.
 | 
			
		||||
	 */
 | 
			
		||||
	PreparedStatement createPreparedStatement(Connection con) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,321 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
 | 
			
		||||
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper class that efficiently creates multiple {@link PreparedStatementCreator}
 | 
			
		||||
 * objects with different parameters based on a SQL statement and a single
 | 
			
		||||
 * set of parameter declarations.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 */
 | 
			
		||||
public class PreparedStatementCreatorFactory {
 | 
			
		||||
 | 
			
		||||
	/** The SQL, which won't change when the parameters change */
 | 
			
		||||
	private final String sql;
 | 
			
		||||
 | 
			
		||||
	/** List of SqlParameter objects. May not be <code>null</code>. */
 | 
			
		||||
	private final List declaredParameters;
 | 
			
		||||
 | 
			
		||||
	private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
 | 
			
		||||
 | 
			
		||||
	private boolean updatableResults = false;
 | 
			
		||||
 | 
			
		||||
	private boolean returnGeneratedKeys = false;
 | 
			
		||||
 | 
			
		||||
	private String[] generatedKeysColumnNames = null;
 | 
			
		||||
 | 
			
		||||
	private NativeJdbcExtractor nativeJdbcExtractor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new factory. Will need to add parameters via the
 | 
			
		||||
	 * {@link #addParameter} method or have no parameters.
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementCreatorFactory(String sql) {
 | 
			
		||||
		this.sql = sql;
 | 
			
		||||
		this.declaredParameters = new LinkedList();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new factory with the given SQL and JDBC types.
 | 
			
		||||
	 * @param sql SQL to execute
 | 
			
		||||
	 * @param types int array of JDBC types
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementCreatorFactory(String sql, int[] types) {
 | 
			
		||||
		this.sql = sql;
 | 
			
		||||
		this.declaredParameters = SqlParameter.sqlTypesToAnonymousParameterList(types);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new factory with the given SQL and parameters.
 | 
			
		||||
	 * @param sql SQL
 | 
			
		||||
	 * @param declaredParameters list of {@link SqlParameter} objects
 | 
			
		||||
	 * @see SqlParameter
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementCreatorFactory(String sql, List declaredParameters) {
 | 
			
		||||
		this.sql = sql;
 | 
			
		||||
		this.declaredParameters = declaredParameters;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a new declared parameter.
 | 
			
		||||
	 * <p>Order of parameter addition is significant.
 | 
			
		||||
	 * @param param the parameter to add to the list of declared parameters
 | 
			
		||||
	 */
 | 
			
		||||
	public void addParameter(SqlParameter param) {
 | 
			
		||||
		this.declaredParameters.add(param);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether to use prepared statements that return a specific type of ResultSet.
 | 
			
		||||
	 * @param resultSetType the ResultSet type
 | 
			
		||||
	 * @see java.sql.ResultSet#TYPE_FORWARD_ONLY
 | 
			
		||||
	 * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE
 | 
			
		||||
	 * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE
 | 
			
		||||
	 */
 | 
			
		||||
	public void setResultSetType(int resultSetType) {
 | 
			
		||||
		this.resultSetType = resultSetType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether to use prepared statements capable of returning updatable ResultSets.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setUpdatableResults(boolean updatableResults) {
 | 
			
		||||
		this.updatableResults = updatableResults;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set whether prepared statements should be capable of returning auto-generated keys.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setReturnGeneratedKeys(boolean returnGeneratedKeys) {
 | 
			
		||||
		this.returnGeneratedKeys = returnGeneratedKeys;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the column names of the auto-generated keys.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setGeneratedKeysColumnNames(String[] names) {
 | 
			
		||||
		this.generatedKeysColumnNames = names;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the NativeJdbcExtractor to use for unwrapping PreparedStatements, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
 | 
			
		||||
		this.nativeJdbcExtractor = nativeJdbcExtractor;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a new PreparedStatementSetter for the given parameters.
 | 
			
		||||
	 * @param params list of parameters (may be <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementSetter newPreparedStatementSetter(List params) {
 | 
			
		||||
		return new PreparedStatementCreatorImpl(params != null ? params : Collections.EMPTY_LIST);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a new PreparedStatementSetter for the given parameters.
 | 
			
		||||
	 * @param params the parameter array (may be <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementSetter newPreparedStatementSetter(Object[] params) {
 | 
			
		||||
		return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.EMPTY_LIST);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a new PreparedStatementCreator for the given parameters.
 | 
			
		||||
	 * @param params list of parameters (may be <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementCreator newPreparedStatementCreator(List params) {
 | 
			
		||||
		return new PreparedStatementCreatorImpl(params != null ? params : Collections.EMPTY_LIST);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a new PreparedStatementCreator for the given parameters.
 | 
			
		||||
	 * @param params the parameter array (may be <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementCreator newPreparedStatementCreator(Object[] params) {
 | 
			
		||||
		return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.EMPTY_LIST);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a new PreparedStatementCreator for the given parameters.
 | 
			
		||||
	 * @param sqlToUse the actual SQL statement to use (if different from
 | 
			
		||||
	 * the factory's, for example because of named parameter expanding)
 | 
			
		||||
	 * @param params the parameter array (may be <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	public PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object[] params) {
 | 
			
		||||
		return new PreparedStatementCreatorImpl(
 | 
			
		||||
				sqlToUse, params != null ? Arrays.asList(params) : Collections.EMPTY_LIST);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * PreparedStatementCreator implementation returned by this class.
 | 
			
		||||
	 */
 | 
			
		||||
	private class PreparedStatementCreatorImpl
 | 
			
		||||
			implements PreparedStatementCreator, PreparedStatementSetter, SqlProvider, ParameterDisposer {
 | 
			
		||||
 | 
			
		||||
		private final String actualSql;
 | 
			
		||||
 | 
			
		||||
		private final List parameters;
 | 
			
		||||
 | 
			
		||||
		public PreparedStatementCreatorImpl(List parameters) {
 | 
			
		||||
			this(sql, parameters);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PreparedStatementCreatorImpl(String actualSql, List parameters) {
 | 
			
		||||
			this.actualSql = actualSql;
 | 
			
		||||
			Assert.notNull(parameters, "Parameters List must not be null");
 | 
			
		||||
			this.parameters = parameters;
 | 
			
		||||
			if (this.parameters.size() != declaredParameters.size()) {
 | 
			
		||||
				// account for named parameters being used multiple times
 | 
			
		||||
				Set names = new HashSet();
 | 
			
		||||
				for (int i = 0; i < parameters.size(); i++) {
 | 
			
		||||
					Object o = parameters.get(i);
 | 
			
		||||
					if (o instanceof SqlParameterValue) {
 | 
			
		||||
						names.add(((SqlParameterValue)o).getName());
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						names.add("Parameter #" + i);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (names.size() != declaredParameters.size()) {
 | 
			
		||||
					throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
							"SQL [" + sql + "]: given " + names.size() +
 | 
			
		||||
							" parameters but expected " + declaredParameters.size());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
 | 
			
		||||
			PreparedStatement ps = null;
 | 
			
		||||
			if (generatedKeysColumnNames != null || returnGeneratedKeys) {
 | 
			
		||||
				try {
 | 
			
		||||
					if (generatedKeysColumnNames != null) {
 | 
			
		||||
						ps = con.prepareStatement(this.actualSql, generatedKeysColumnNames);
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						ps = con.prepareStatement(this.actualSql, PreparedStatement.RETURN_GENERATED_KEYS);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				catch (AbstractMethodError ex) {
 | 
			
		||||
					throw new InvalidDataAccessResourceUsageException(
 | 
			
		||||
							"The JDBC driver is not compliant to JDBC 3.0 and thus " +
 | 
			
		||||
							"does not support retrieval of auto-generated keys", ex);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) {
 | 
			
		||||
				ps = con.prepareStatement(this.actualSql);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ps = con.prepareStatement(this.actualSql, resultSetType,
 | 
			
		||||
					updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY);
 | 
			
		||||
			}
 | 
			
		||||
			setValues(ps);
 | 
			
		||||
			return ps;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void setValues(PreparedStatement ps) throws SQLException {
 | 
			
		||||
			// Determine PreparedStatement to pass to custom types.
 | 
			
		||||
			PreparedStatement psToUse = ps;
 | 
			
		||||
			if (nativeJdbcExtractor != null) {
 | 
			
		||||
				psToUse = nativeJdbcExtractor.getNativePreparedStatement(ps);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Set arguments: Does nothing if there are no parameters.
 | 
			
		||||
			int sqlColIndx = 1;
 | 
			
		||||
			for (int i = 0; i < this.parameters.size(); i++) {
 | 
			
		||||
				Object in = this.parameters.get(i);
 | 
			
		||||
				SqlParameter declaredParameter = null;
 | 
			
		||||
				// SqlParameterValue overrides declared parameter metadata, in particular for
 | 
			
		||||
				// independence from the declared parameter position in case of named parameters.
 | 
			
		||||
				if (in instanceof SqlParameterValue) {
 | 
			
		||||
					SqlParameterValue paramValue = (SqlParameterValue) in;
 | 
			
		||||
					in = paramValue.getValue();
 | 
			
		||||
					declaredParameter = paramValue;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					if (declaredParameters.size() <= i) {
 | 
			
		||||
						throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
								"SQL [" + sql + "]: unable to access parameter number " + (i + 1) +
 | 
			
		||||
								" given only " + declaredParameters.size() + " parameters");
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
					declaredParameter = (SqlParameter) declaredParameters.get(i);
 | 
			
		||||
				}
 | 
			
		||||
				if (in instanceof Collection && declaredParameter.getSqlType() != Types.ARRAY) {
 | 
			
		||||
					Collection entries = (Collection) in;
 | 
			
		||||
					for (Iterator it = entries.iterator(); it.hasNext();) {
 | 
			
		||||
						Object entry = it.next();
 | 
			
		||||
						if (entry instanceof Object[]) {
 | 
			
		||||
							Object[] valueArray = ((Object[])entry);
 | 
			
		||||
							for (int k = 0; k < valueArray.length; k++) {
 | 
			
		||||
								Object argValue = valueArray[k];
 | 
			
		||||
								StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, argValue);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, entry);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, in);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String getSql() {
 | 
			
		||||
			return sql;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void cleanupParameters() {
 | 
			
		||||
			StatementCreatorUtils.cleanupParameters(this.parameters);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String toString() {
 | 
			
		||||
			StringBuffer buf = new StringBuffer("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: sql=[");
 | 
			
		||||
			buf.append(sql).append("]; parameters=").append(this.parameters);
 | 
			
		||||
			return buf.toString();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * General callback interface used by the {@link JdbcTemplate} class.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This interface sets values on a {@link java.sql.PreparedStatement} provided
 | 
			
		||||
 * by the JdbcTemplate class, for each of a number of updates in a batch using the
 | 
			
		||||
 * same SQL. Implementations are responsible for setting any necessary parameters.
 | 
			
		||||
 * SQL with placeholders will already have been supplied.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>It's easier to use this interface than {@link PreparedStatementCreator}:
 | 
			
		||||
 * The JdbcTemplate will create the PreparedStatement, with the callback
 | 
			
		||||
 * only being responsible for setting parameter values.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Implementations <i>do not</i> need to concern themselves with
 | 
			
		||||
 * SQLExceptions that may be thrown from operations they attempt.
 | 
			
		||||
 * The JdbcTemplate class will catch and handle SQLExceptions appropriately.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @since March 2, 2003
 | 
			
		||||
 * @see JdbcTemplate#update(String, PreparedStatementSetter)
 | 
			
		||||
 * @see JdbcTemplate#query(String, PreparedStatementSetter, ResultSetExtractor)
 | 
			
		||||
 */
 | 
			
		||||
public interface PreparedStatementSetter {
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Set parameter values on the given PreparedStatement.
 | 
			
		||||
	 * @param ps the PreparedStatement to invoke setter methods on
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered
 | 
			
		||||
	 * (i.e. there is no need to catch SQLException)
 | 
			
		||||
	 */
 | 
			
		||||
	void setValues(PreparedStatement ps) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * Callback interface used by {@link JdbcTemplate}'s query methods.
 | 
			
		||||
 * Implementations of this interface perform the actual work of extracting
 | 
			
		||||
 * results from a {@link java.sql.ResultSet}, but don't need to worry
 | 
			
		||||
 * about exception handling. {@link java.sql.SQLException SQLExceptions}
 | 
			
		||||
 * will be caught and handled by the calling JdbcTemplate.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This interface is mainly used within the JDBC framework itself.
 | 
			
		||||
 * A {@link RowMapper} is usually a simpler choice for ResultSet processing,
 | 
			
		||||
 * mapping one result object per row instead of one result object for
 | 
			
		||||
 * the entire ResultSet.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Note: In contrast to a {@link RowCallbackHandler}, a ResultSetExtractor
 | 
			
		||||
 * object is typically stateless and thus reusable, as long as it doesn't
 | 
			
		||||
 * access stateful resources (such as output streams when streaming LOB
 | 
			
		||||
 * contents) or keep result state within the object.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since April 24, 2003
 | 
			
		||||
 * @see JdbcTemplate
 | 
			
		||||
 * @see RowCallbackHandler
 | 
			
		||||
 * @see RowMapper
 | 
			
		||||
 * @see org.springframework.jdbc.core.support.AbstractLobStreamingResultSetExtractor
 | 
			
		||||
 */
 | 
			
		||||
public interface ResultSetExtractor {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Implementations must implement this method to process the entire ResultSet.
 | 
			
		||||
	 * @param rs ResultSet to extract data from. Implementations should
 | 
			
		||||
	 * not close this: it will be closed by the calling JdbcTemplate.
 | 
			
		||||
	 * @return an arbitrary result object, or <code>null</code> if none
 | 
			
		||||
	 * (the extractor will typically be stateful in the latter case).
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered getting column
 | 
			
		||||
	 * values or navigating (that is, there's no need to catch SQLException)
 | 
			
		||||
	 * @throws DataAccessException in case of custom exceptions
 | 
			
		||||
	 */
 | 
			
		||||
	Object extractData(ResultSet rs) throws SQLException, DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Common base class for ResultSet-supporting SqlParameters like
 | 
			
		||||
 * {@link SqlOutParameter} and {@link SqlReturnResultSet}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.0.2
 | 
			
		||||
 */
 | 
			
		||||
public class ResultSetSupportingSqlParameter extends SqlParameter {
 | 
			
		||||
 | 
			
		||||
	private ResultSetExtractor resultSetExtractor;
 | 
			
		||||
 | 
			
		||||
	private RowCallbackHandler rowCallbackHandler;
 | 
			
		||||
 | 
			
		||||
	private RowMapper rowMapper;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ResultSetSupportingSqlParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	public ResultSetSupportingSqlParameter(String name, int sqlType) {
 | 
			
		||||
		super(name, sqlType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ResultSetSupportingSqlParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param scale the number of digits after the decimal point
 | 
			
		||||
	 * (for DECIMAL and NUMERIC types)
 | 
			
		||||
	 */
 | 
			
		||||
	public ResultSetSupportingSqlParameter(String name, int sqlType, int scale) {
 | 
			
		||||
		super(name, sqlType, scale);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ResultSetSupportingSqlParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 */
 | 
			
		||||
	public ResultSetSupportingSqlParameter(String name, int sqlType, String typeName) {
 | 
			
		||||
		super(name, sqlType, typeName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ResultSetSupportingSqlParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rse ResultSetExtractor to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public ResultSetSupportingSqlParameter(String name, int sqlType, ResultSetExtractor rse) {
 | 
			
		||||
		super(name, sqlType);
 | 
			
		||||
		this.resultSetExtractor = rse;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ResultSetSupportingSqlParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rch RowCallbackHandler to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public ResultSetSupportingSqlParameter(String name, int sqlType, RowCallbackHandler rch) {
 | 
			
		||||
		super(name, sqlType);
 | 
			
		||||
		this.rowCallbackHandler = rch;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ResultSetSupportingSqlParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rm RowMapper to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public ResultSetSupportingSqlParameter(String name, int sqlType, RowMapper rm) {
 | 
			
		||||
		super(name, sqlType);
 | 
			
		||||
		this.rowMapper = rm;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this parameter support a ResultSet, i.e. does it hold a
 | 
			
		||||
	 * ResultSetExtractor, RowCallbackHandler or RowMapper?
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isResultSetSupported() {
 | 
			
		||||
		return (this.resultSetExtractor != null || this.rowCallbackHandler != null || this.rowMapper != null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the ResultSetExtractor held by this parameter, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public ResultSetExtractor getResultSetExtractor() {
 | 
			
		||||
		return resultSetExtractor;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the RowCallbackHandler held by this parameter, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public RowCallbackHandler getRowCallbackHandler() {
 | 
			
		||||
		return this.rowCallbackHandler;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the RowMapper held by this parameter, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public RowMapper getRowMapper() {
 | 
			
		||||
		return this.rowMapper;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>This implementation always returns <code>false</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isInputValueProvided() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An interface used by {@link JdbcTemplate} for processing rows of a
 | 
			
		||||
 * {@link java.sql.ResultSet} on a per-row basis. Implementations of
 | 
			
		||||
 * this interface perform the actual work of processing each row
 | 
			
		||||
 * but don't need to worry about exception handling.
 | 
			
		||||
 * {@link java.sql.SQLException SQLExceptions} will be caught and handled
 | 
			
		||||
 * by the calling JdbcTemplate.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>In contrast to a {@link ResultSetExtractor}, a RowCallbackHandler
 | 
			
		||||
 * object is typically stateful: It keeps the result state within the
 | 
			
		||||
 * object, to be available for later inspection. See
 | 
			
		||||
 * {@link RowCountCallbackHandler} for a usage example.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Consider using a {@link RowMapper} instead if you need to map
 | 
			
		||||
 * exactly one result object per row, assembling them into a List.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @see JdbcTemplate
 | 
			
		||||
 * @see RowMapper
 | 
			
		||||
 * @see ResultSetExtractor
 | 
			
		||||
 * @see RowCountCallbackHandler
 | 
			
		||||
 */
 | 
			
		||||
public interface RowCallbackHandler {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Implementations must implement this method to process each row of data
 | 
			
		||||
	 * in the ResultSet. This method should not call <code>next()</code> on
 | 
			
		||||
	 * the ResultSet; it is only supposed to extract values of the current row.
 | 
			
		||||
	 * <p>Exactly what the implementation chooses to do is up to it:
 | 
			
		||||
	 * A trivial implementation might simply count rows, while another
 | 
			
		||||
	 * implementation might build an XML document.
 | 
			
		||||
	 * @param rs the ResultSet to process (pre-initialized for the current row)
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered getting
 | 
			
		||||
	 * column values (that is, there's no need to catch SQLException)
 | 
			
		||||
	 */
 | 
			
		||||
	void processRow(ResultSet rs) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,137 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.ResultSetMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implementation of RowCallbackHandler. Convenient superclass for callback handlers.
 | 
			
		||||
 * An instance can only be used once.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>We can either use this on its own (for example, in a test case, to ensure
 | 
			
		||||
 * that our result sets have valid dimensions), or use it as a superclass
 | 
			
		||||
 * for callback handlers that actually do something, and will benefit
 | 
			
		||||
 * from the dimension information it provides.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A usage example with JdbcTemplate:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 | 
			
		||||
 * 
 | 
			
		||||
 * RowCountCallbackHandler countCallback = new RowCountCallbackHandler();  // not reusable
 | 
			
		||||
 * jdbcTemplate.query("select * from user", countCallback);
 | 
			
		||||
 * int rowCount = countCallback.getRowCount();</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @since May 3, 2001
 | 
			
		||||
 */
 | 
			
		||||
public class RowCountCallbackHandler implements RowCallbackHandler {
 | 
			
		||||
 | 
			
		||||
	/** Rows we've seen so far */
 | 
			
		||||
	private int rowCount;
 | 
			
		||||
 | 
			
		||||
	/** Columns we've seen so far */
 | 
			
		||||
	private int columnCount;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Indexed from 0. Type (as in java.sql.Types) for the columns
 | 
			
		||||
	 * as returned by ResultSetMetaData object.
 | 
			
		||||
	 */
 | 
			
		||||
	private int[] columnTypes;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Indexed from 0. Column name as returned by ResultSetMetaData object.
 | 
			
		||||
	 */
 | 
			
		||||
	private String[] columnNames;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Implementation of ResultSetCallbackHandler.
 | 
			
		||||
	 * Work out column size if this is the first row, otherwise just count rows.
 | 
			
		||||
	 * <p>Subclasses can perform custom extraction or processing
 | 
			
		||||
	 * by overriding the <code>processRow(ResultSet, int)</code> method.
 | 
			
		||||
	 * @see #processRow(java.sql.ResultSet, int)
 | 
			
		||||
	 */
 | 
			
		||||
	public final void processRow(ResultSet rs) throws SQLException {
 | 
			
		||||
		if (this.rowCount == 0) {
 | 
			
		||||
			ResultSetMetaData rsmd = rs.getMetaData();
 | 
			
		||||
			this.columnCount = rsmd.getColumnCount();
 | 
			
		||||
			this.columnTypes = new int[this.columnCount];
 | 
			
		||||
			this.columnNames = new String[this.columnCount];
 | 
			
		||||
			for (int i = 0; i < this.columnCount; i++) {
 | 
			
		||||
				this.columnTypes[i] = rsmd.getColumnType(i + 1);
 | 
			
		||||
				this.columnNames[i] = JdbcUtils.lookupColumnName(rsmd, i + 1);
 | 
			
		||||
			}
 | 
			
		||||
			// could also get column names
 | 
			
		||||
		}
 | 
			
		||||
		processRow(rs, this.rowCount++);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Subclasses may override this to perform custom extraction
 | 
			
		||||
	 * or processing. This class's implementation does nothing.
 | 
			
		||||
	 * @param rs ResultSet to extract data from. This method is
 | 
			
		||||
	 * invoked for each row
 | 
			
		||||
	 * @param rowNum number of the current row (starting from 0)
 | 
			
		||||
	 */
 | 
			
		||||
	protected void processRow(ResultSet rs, int rowNum) throws SQLException {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the types of the columns as java.sql.Types constants
 | 
			
		||||
	 * Valid after processRow is invoked the first time.
 | 
			
		||||
	 * @return the types of the columns as java.sql.Types constants.
 | 
			
		||||
	 * <b>Indexed from 0 to n-1.</b>
 | 
			
		||||
	 */
 | 
			
		||||
	public final int[] getColumnTypes() {
 | 
			
		||||
		return columnTypes;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Return the names of the columns.
 | 
			
		||||
	 * Valid after processRow is invoked the first time.
 | 
			
		||||
	 * @return the names of the columns.
 | 
			
		||||
	 * <b>Indexed from 0 to n-1.</b>
 | 
			
		||||
	 */
 | 
			
		||||
	public final String[] getColumnNames() {
 | 
			
		||||
		return columnNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Return the row count of this ResultSet
 | 
			
		||||
	 * Only valid after processing is complete
 | 
			
		||||
	 * @return the number of rows in this ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public final int getRowCount() {
 | 
			
		||||
		return rowCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Return the number of columns in this result set.
 | 
			
		||||
	 * Valid once we've seen the first row,
 | 
			
		||||
	 * so subclasses can use it during processing
 | 
			
		||||
	 * @return the number of columns in this result set
 | 
			
		||||
	 */
 | 
			
		||||
	public final int getColumnCount() {
 | 
			
		||||
		return columnCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An interface used by {@link JdbcTemplate} for mapping rows of a
 | 
			
		||||
 * {@link java.sql.ResultSet} on a per-row basis. Implementations of this
 | 
			
		||||
 * interface perform the actual work of mapping each row to a result object,
 | 
			
		||||
 * but don't need to worry about exception handling.
 | 
			
		||||
 * {@link java.sql.SQLException SQLExceptions} will be caught and handled
 | 
			
		||||
 * by the calling JdbcTemplate.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Typically used either for {@link JdbcTemplate}'s query methods
 | 
			
		||||
 * or for out parameters of stored procedures. RowMapper objects are
 | 
			
		||||
 * typically stateless and thus reusable; they are an ideal choice for
 | 
			
		||||
 * implementing row-mapping logic in a single place.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Alternatively, consider subclassing
 | 
			
		||||
 * {@link org.springframework.jdbc.object.MappingSqlQuery} from the
 | 
			
		||||
 * <code>jdbc.object</code> package: Instead of working with separate
 | 
			
		||||
 * JdbcTemplate and RowMapper objects, you can build executable query
 | 
			
		||||
 * objects (containing row-mapping logic) in that style.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @see JdbcTemplate
 | 
			
		||||
 * @see RowCallbackHandler
 | 
			
		||||
 * @see ResultSetExtractor
 | 
			
		||||
 * @see org.springframework.jdbc.object.MappingSqlQuery
 | 
			
		||||
 */
 | 
			
		||||
public interface RowMapper {
 | 
			
		||||
 | 
			
		||||
	/** 
 | 
			
		||||
	 * Implementations must implement this method to map each row of data
 | 
			
		||||
	 * in the ResultSet. This method should not call <code>next()</code> on
 | 
			
		||||
	 * the ResultSet; it is only supposed to map values of the current row.
 | 
			
		||||
	 * @param rs the ResultSet to map (pre-initialized for the current row)
 | 
			
		||||
	 * @param rowNum the number of the current row
 | 
			
		||||
	 * @return the result object for the current row
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered getting
 | 
			
		||||
	 * column values (that is, there's no need to catch SQLException)
 | 
			
		||||
	 */
 | 
			
		||||
	Object mapRow(ResultSet rs, int rowNum) throws SQLException; 
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,97 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adapter implementation of the ResultSetExtractor interface that delegates
 | 
			
		||||
 * to a RowMapper which is supposed to create an object for each row.
 | 
			
		||||
 * Each object is added to the results List of this ResultSetExtractor.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Useful for the typical case of one object per row in the database table.
 | 
			
		||||
 * The number of entries in the results list will match the number of rows.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Note that a RowMapper object is typically stateless and thus reusable;
 | 
			
		||||
 * just the RowMapperResultSetExtractor adapter is stateful.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A usage example with JdbcTemplate:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 | 
			
		||||
 * RowMapper rowMapper = new UserRowMapper();  // reusable object
 | 
			
		||||
 *
 | 
			
		||||
 * List allUsers = (List) jdbcTemplate.query(
 | 
			
		||||
 *     "select * from user",
 | 
			
		||||
 *     new RowMapperResultSetExtractor(rowMapper, 10));
 | 
			
		||||
 *
 | 
			
		||||
 * User user = (User) jdbcTemplate.queryForObject(
 | 
			
		||||
 *     "select * from user where id=?", new Object[] {id},
 | 
			
		||||
 *     new RowMapperResultSetExtractor(rowMapper, 1));</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Alternatively, consider subclassing MappingSqlQuery from the <code>jdbc.object</code>
 | 
			
		||||
 * package: Instead of working with separate JdbcTemplate and RowMapper objects,
 | 
			
		||||
 * you can have executable query objects (containing row-mapping logic) there.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.0.2
 | 
			
		||||
 * @see RowMapper
 | 
			
		||||
 * @see JdbcTemplate
 | 
			
		||||
 * @see org.springframework.jdbc.object.MappingSqlQuery
 | 
			
		||||
 */
 | 
			
		||||
public class RowMapperResultSetExtractor implements ResultSetExtractor {
 | 
			
		||||
 | 
			
		||||
	private final RowMapper rowMapper;
 | 
			
		||||
 | 
			
		||||
	private final int rowsExpected;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new RowMapperResultSetExtractor.
 | 
			
		||||
	 * @param rowMapper the RowMapper which creates an object for each row
 | 
			
		||||
	 */
 | 
			
		||||
	public RowMapperResultSetExtractor(RowMapper rowMapper) {
 | 
			
		||||
		this(rowMapper, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new RowMapperResultSetExtractor.
 | 
			
		||||
	 * @param rowMapper the RowMapper which creates an object for each row
 | 
			
		||||
	 * @param rowsExpected the number of expected rows
 | 
			
		||||
	 * (just used for optimized collection handling)
 | 
			
		||||
	 */
 | 
			
		||||
	public RowMapperResultSetExtractor(RowMapper rowMapper, int rowsExpected) {
 | 
			
		||||
		Assert.notNull(rowMapper, "RowMapper is required");
 | 
			
		||||
		this.rowMapper = rowMapper;
 | 
			
		||||
		this.rowsExpected = rowsExpected;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public Object extractData(ResultSet rs) throws SQLException {
 | 
			
		||||
		List results = (this.rowsExpected > 0 ? new ArrayList(this.rowsExpected) : new ArrayList());
 | 
			
		||||
		int rowNum = 0;
 | 
			
		||||
		while (rs.next()) {
 | 
			
		||||
			results.add(this.rowMapper.mapRow(rs, rowNum++));
 | 
			
		||||
		}
 | 
			
		||||
		return results;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,185 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.ResultSetMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.TypeMismatchDataAccessException;
 | 
			
		||||
import org.springframework.jdbc.IncorrectResultSetColumnCountException;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
import org.springframework.util.NumberUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link RowMapper} implementation that converts a single column into a single
 | 
			
		||||
 * result value per row. Expects to operate on a <code>java.sql.ResultSet</code>
 | 
			
		||||
 * that just contains a single column.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The type of the result value for each row can be specified. The value
 | 
			
		||||
 * for the single column will be extracted from the <code>ResultSet</code>
 | 
			
		||||
 * and converted into the specified target type.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.2
 | 
			
		||||
 * @see JdbcTemplate#queryForList(String, Class)
 | 
			
		||||
 * @see JdbcTemplate#queryForObject(String, Class)
 | 
			
		||||
 */
 | 
			
		||||
public class SingleColumnRowMapper implements RowMapper {
 | 
			
		||||
 | 
			
		||||
	private Class requiredType;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SingleColumnRowMapper.
 | 
			
		||||
	 * @see #setRequiredType
 | 
			
		||||
	 */
 | 
			
		||||
	public SingleColumnRowMapper() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SingleColumnRowMapper.
 | 
			
		||||
	 * @param requiredType the type that each result object is expected to match
 | 
			
		||||
	 */
 | 
			
		||||
	public SingleColumnRowMapper(Class requiredType) {
 | 
			
		||||
		this.requiredType = requiredType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the type that each result object is expected to match.
 | 
			
		||||
	 * <p>If not specified, the column value will be exposed as
 | 
			
		||||
	 * returned by the JDBC driver.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setRequiredType(Class requiredType) {
 | 
			
		||||
		this.requiredType = requiredType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Extract a value for the single column in the current row.
 | 
			
		||||
	 * <p>Validates that there is only one column selected,
 | 
			
		||||
	 * then delegates to <code>getColumnValue()</code> and also
 | 
			
		||||
	 * <code>convertValueToRequiredType</code>, if necessary.
 | 
			
		||||
	 * @see java.sql.ResultSetMetaData#getColumnCount()
 | 
			
		||||
	 * @see #getColumnValue(java.sql.ResultSet, int, Class)
 | 
			
		||||
	 * @see #convertValueToRequiredType(Object, Class)
 | 
			
		||||
	 */
 | 
			
		||||
	public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
 | 
			
		||||
		// Validate column count.
 | 
			
		||||
		ResultSetMetaData rsmd = rs.getMetaData();
 | 
			
		||||
		int nrOfColumns = rsmd.getColumnCount();
 | 
			
		||||
		if (nrOfColumns != 1) {
 | 
			
		||||
			throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Extract column value from JDBC ResultSet.
 | 
			
		||||
		Object result = getColumnValue(rs, 1, this.requiredType);
 | 
			
		||||
		if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
 | 
			
		||||
			// Extracted value does not match already: try to convert it.
 | 
			
		||||
			try {
 | 
			
		||||
				return convertValueToRequiredType(result, this.requiredType);
 | 
			
		||||
			}
 | 
			
		||||
			catch (IllegalArgumentException ex) {
 | 
			
		||||
				throw new TypeMismatchDataAccessException(
 | 
			
		||||
						"Type mismatch affecting row number " + rowNum + " and column type '" +
 | 
			
		||||
						rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Retrieve a JDBC object value for the specified column.
 | 
			
		||||
	 * <p>The default implementation calls
 | 
			
		||||
	 * {@link JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class)}.
 | 
			
		||||
	 * If no required type has been specified, this method delegates to
 | 
			
		||||
	 * <code>getColumnValue(rs, index)</code>, which basically calls
 | 
			
		||||
	 * <code>ResultSet.getObject(index)</code> but applies some additional
 | 
			
		||||
	 * default conversion to appropriate value types.
 | 
			
		||||
	 * @param rs is the ResultSet holding the data
 | 
			
		||||
	 * @param index is the column index
 | 
			
		||||
	 * @param requiredType the type that each result object is expected to match
 | 
			
		||||
	 * (or <code>null</code> if none specified)
 | 
			
		||||
	 * @return the Object value
 | 
			
		||||
	 * @throws SQLException in case of extraction failure
 | 
			
		||||
	 * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class)
 | 
			
		||||
	 * @see #getColumnValue(java.sql.ResultSet, int)
 | 
			
		||||
	 */
 | 
			
		||||
	protected Object getColumnValue(ResultSet rs, int index, Class requiredType) throws SQLException {
 | 
			
		||||
		if (requiredType != null) {
 | 
			
		||||
			return JdbcUtils.getResultSetValue(rs, index, requiredType);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			// No required type specified -> perform default extraction.
 | 
			
		||||
			return getColumnValue(rs, index);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Retrieve a JDBC object value for the specified column, using the most
 | 
			
		||||
	 * appropriate value type. Called if no required type has been specified.
 | 
			
		||||
	 * <p>The default implementation delegates to <code>JdbcUtils.getResultSetValue()</code>,
 | 
			
		||||
	 * which uses the <code>ResultSet.getObject(index)</code> method. Additionally,
 | 
			
		||||
	 * it includes a "hack" to get around Oracle returning a non-standard object for
 | 
			
		||||
	 * their TIMESTAMP datatype. See the <code>JdbcUtils#getResultSetValue()</code>
 | 
			
		||||
	 * javadoc for details.
 | 
			
		||||
	 * @param rs is the ResultSet holding the data
 | 
			
		||||
	 * @param index is the column index
 | 
			
		||||
	 * @return the Object value
 | 
			
		||||
	 * @throws SQLException in case of extraction failure
 | 
			
		||||
	 * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet, int)
 | 
			
		||||
	 */
 | 
			
		||||
	protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
 | 
			
		||||
		return JdbcUtils.getResultSetValue(rs, index);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert the given column value to the specified required type.
 | 
			
		||||
	 * Only called if the extracted column value does not match already.
 | 
			
		||||
	 * <p>If the required type is String, the value will simply get stringified
 | 
			
		||||
	 * via <code>toString()</code>. In case of a Number, the value will be
 | 
			
		||||
	 * converted into a Number, either through number conversion or through
 | 
			
		||||
	 * String parsing (depending on the value type).
 | 
			
		||||
	 * @param value the column value as extracted from <code>getColumnValue()</code>
 | 
			
		||||
	 * (never <code>null</code>)
 | 
			
		||||
	 * @param requiredType the type that each result object is expected to match
 | 
			
		||||
	 * (never <code>null</code>)
 | 
			
		||||
	 * @return the converted value
 | 
			
		||||
	 * @see #getColumnValue(java.sql.ResultSet, int, Class)
 | 
			
		||||
	 */
 | 
			
		||||
	protected Object convertValueToRequiredType(Object value, Class requiredType) {
 | 
			
		||||
		if (String.class.equals(requiredType)) {
 | 
			
		||||
			return value.toString();
 | 
			
		||||
		}
 | 
			
		||||
		else if (Number.class.isAssignableFrom(requiredType)) {
 | 
			
		||||
			if (value instanceof Number) {
 | 
			
		||||
				// Convert original Number to target Number class.
 | 
			
		||||
				return NumberUtils.convertNumberToTargetClass(((Number) value), requiredType);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				// Convert stringified value to target Number class.
 | 
			
		||||
				return NumberUtils.parseNumber(value.toString(), requiredType);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			throw new IllegalArgumentException(
 | 
			
		||||
					"Value [" + value + "] is of type [" + value.getClass().getName() +
 | 
			
		||||
					"] and cannot be converted to required type [" + requiredType.getName() + "]");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,112 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of {@link SqlOutParameter} to represent an INOUT parameter.
 | 
			
		||||
 * Will return <code>true</code> for SqlParameter's {@link #isInputValueProvided}
 | 
			
		||||
 * test, in contrast to a standard SqlOutParameter.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Output parameters - like all stored procedure parameters -
 | 
			
		||||
 * must have names.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 */
 | 
			
		||||
public class SqlInOutParameter extends SqlOutParameter {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlInOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlInOutParameter(String name, int sqlType) {
 | 
			
		||||
		super(name, sqlType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlInOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param scale the number of digits after the decimal point
 | 
			
		||||
	 * (for DECIMAL and NUMERIC types)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlInOutParameter(String name, int sqlType, int scale) {
 | 
			
		||||
		super(name, sqlType, scale);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlInOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlInOutParameter(String name, int sqlType, String typeName) {
 | 
			
		||||
		super(name, sqlType, typeName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlInOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 * @param sqlReturnType custom value handler for complex type (optional)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlInOutParameter(String name, int sqlType, String typeName, SqlReturnType sqlReturnType) {
 | 
			
		||||
		super(name, sqlType, typeName, sqlReturnType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlInOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rse ResultSetExtractor to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlInOutParameter(String name, int sqlType, ResultSetExtractor rse) {
 | 
			
		||||
		super(name, sqlType, rse);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlInOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rch RowCallbackHandler to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlInOutParameter(String name, int sqlType, RowCallbackHandler rch) {
 | 
			
		||||
		super(name, sqlType, rch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlInOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rm RowMapper to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlInOutParameter(String name, int sqlType, RowMapper rm) {
 | 
			
		||||
		super(name, sqlType, rm);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This implementation always returns <code>true</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isInputValueProvided() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,125 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Subclass of SqlParameter to represent an output parameter.
 | 
			
		||||
 * No additional properties: instanceof will be used to check
 | 
			
		||||
 * for such types.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Output parameters - like all stored procedure parameters -
 | 
			
		||||
 * must have names.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @see SqlReturnResultSet
 | 
			
		||||
 * @see SqlInOutParameter
 | 
			
		||||
 */
 | 
			
		||||
public class SqlOutParameter extends ResultSetSupportingSqlParameter {
 | 
			
		||||
 | 
			
		||||
	private SqlReturnType sqlReturnType;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlOutParameter(String name, int sqlType) {
 | 
			
		||||
		super(name, sqlType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param scale the number of digits after the decimal point
 | 
			
		||||
	 * (for DECIMAL and NUMERIC types)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlOutParameter(String name, int sqlType, int scale) {
 | 
			
		||||
		super(name, sqlType, scale);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlOutParameter(String name, int sqlType, String typeName) {
 | 
			
		||||
		super(name, sqlType, typeName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 * @param sqlReturnType custom value handler for complex type (optional)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlOutParameter(String name, int sqlType, String typeName, SqlReturnType sqlReturnType) {
 | 
			
		||||
		super(name, sqlType, typeName);
 | 
			
		||||
		this.sqlReturnType = sqlReturnType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rse ResultSetExtractor to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlOutParameter(String name, int sqlType, ResultSetExtractor rse) {
 | 
			
		||||
		super(name, sqlType, rse);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rch RowCallbackHandler to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlOutParameter(String name, int sqlType, RowCallbackHandler rch) {
 | 
			
		||||
		super(name, sqlType, rch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlOutParameter.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to java.sql.Types
 | 
			
		||||
	 * @param rm RowMapper to use for parsing the ResultSet
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlOutParameter(String name, int sqlType, RowMapper rm) {
 | 
			
		||||
		super(name, sqlType, rm);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the custom return type, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlReturnType getSqlReturnType() {
 | 
			
		||||
		return this.sqlReturnType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether this parameter holds a custom return type.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isReturnTypeSupported() {
 | 
			
		||||
		return (this.sqlReturnType != null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,190 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Object to represent a SQL parameter definition.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Parameters may be anonymous, in which case "name" is <code>null</code>.
 | 
			
		||||
 * However, all parameters must define a SQL type according to {@link java.sql.Types}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @see java.sql.Types
 | 
			
		||||
 */
 | 
			
		||||
public class SqlParameter {
 | 
			
		||||
 | 
			
		||||
	/** The name of the parameter, if any */
 | 
			
		||||
	private String name;
 | 
			
		||||
 | 
			
		||||
	/** SQL type constant from <code>java.sql.Types</code> */
 | 
			
		||||
	private final int sqlType;
 | 
			
		||||
 | 
			
		||||
	/** Used for types that are user-named like: STRUCT, DISTINCT, JAVA_OBJECT, named array types */
 | 
			
		||||
	private String typeName;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/** The scale to apply in case of a NUMERIC or DECIMAL type, if any */
 | 
			
		||||
	private Integer scale;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new anonymous SqlParameter, supplying the SQL type.
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter(int sqlType) {
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new anonymous SqlParameter, supplying the SQL type.
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter(int sqlType, String typeName) {
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
		this.typeName = typeName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new anonymous SqlParameter, supplying the SQL type.
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 * @param scale the number of digits after the decimal point
 | 
			
		||||
	 * (for DECIMAL and NUMERIC types)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter(int sqlType, int scale) {
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
		this.scale = new Integer(scale);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlParameter, supplying name and SQL type.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter(String name, int sqlType) {
 | 
			
		||||
		this.name = name;
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlParameter, supplying name and SQL type.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter(String name, int sqlType, String typeName) {
 | 
			
		||||
		this.name = name;
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
		this.typeName = typeName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlParameter, supplying name and SQL type.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 * @param scale the number of digits after the decimal point
 | 
			
		||||
	 * (for DECIMAL and NUMERIC types)
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter(String name, int sqlType, int scale) {
 | 
			
		||||
		this.name = name;
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
		this.scale = new Integer(scale);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Copy constructor.
 | 
			
		||||
	 * @param otherParam the SqlParameter object to copy from
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter(SqlParameter otherParam) {
 | 
			
		||||
		Assert.notNull(otherParam, "SqlParameter object must not be null");
 | 
			
		||||
		this.name = otherParam.name;
 | 
			
		||||
		this.sqlType = otherParam.sqlType;
 | 
			
		||||
		this.typeName = otherParam.typeName;
 | 
			
		||||
		this.scale = otherParam.scale;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the name of the parameter.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getName() {
 | 
			
		||||
		return this.name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQL type of the parameter.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getSqlType() {
 | 
			
		||||
		return this.sqlType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the type name of the parameter, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getTypeName() {
 | 
			
		||||
		return this.typeName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the scale of the parameter, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public Integer getScale() {
 | 
			
		||||
		return this.scale;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether this parameter holds input values that should be set
 | 
			
		||||
	 * before execution even if they are <code>null</code>.
 | 
			
		||||
	 * <p>This implementation always returns <code>true</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isInputValueProvided() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether this parameter is an implicit return parameter used during the
 | 
			
		||||
	 * results preocessing of the CallableStatement.getMoreResults/getUpdateCount.
 | 
			
		||||
	 * <p>This implementation always returns <code>false</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isResultsParameter() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert a list of JDBC types, as defined in <code>java.sql.Types</code>,
 | 
			
		||||
	 * to a List of SqlParameter objects as used in this package.
 | 
			
		||||
	 */
 | 
			
		||||
	public static List sqlTypesToAnonymousParameterList(int[] types) {
 | 
			
		||||
		List result = new LinkedList();
 | 
			
		||||
		if (types != null) {
 | 
			
		||||
			for (int i = 0; i < types.length; i++) {
 | 
			
		||||
				result.add(new SqlParameter(types[i]));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Object to represent a SQL parameter value, including parameter metadata
 | 
			
		||||
 * such as the SQL type and the scale for numeric values.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Designed for use with {@link JdbcTemplate}'s operations that take an array of
 | 
			
		||||
 * argument values: Each such argument value may be a <code>SqlParameterValue</code>,
 | 
			
		||||
 * indicating the SQL type (and optionally the scale) instead of letting the
 | 
			
		||||
 * template guess a default type. Note that this only applies to the operations with
 | 
			
		||||
 * a 'plain' argument array, not to the overloaded variants with an explicit type array.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0.5
 | 
			
		||||
 * @see java.sql.Types
 | 
			
		||||
 * @see JdbcTemplate#query(String, Object[], ResultSetExtractor)
 | 
			
		||||
 * @see JdbcTemplate#query(String, Object[], RowCallbackHandler)
 | 
			
		||||
 * @see JdbcTemplate#query(String, Object[], RowMapper)
 | 
			
		||||
 * @see JdbcTemplate#update(String, Object[])
 | 
			
		||||
 */
 | 
			
		||||
public class SqlParameterValue extends SqlParameter {
 | 
			
		||||
 | 
			
		||||
	private final Object value;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlParameterValue, supplying the SQL type.
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 * @param value the value object
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameterValue(int sqlType, Object value) {
 | 
			
		||||
		super(sqlType);
 | 
			
		||||
		this.value = value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlParameterValue, supplying the SQL type.
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 * @param value the value object
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameterValue(int sqlType, String typeName, Object value) {
 | 
			
		||||
		super(sqlType, typeName);
 | 
			
		||||
		this.value = value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlParameterValue, supplying the SQL type.
 | 
			
		||||
	 * @param sqlType SQL type of the parameter according to <code>java.sql.Types</code>
 | 
			
		||||
	 * @param scale the number of digits after the decimal point
 | 
			
		||||
	 * (for DECIMAL and NUMERIC types)
 | 
			
		||||
	 * @param value the value object
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameterValue(int sqlType, int scale, Object value) {
 | 
			
		||||
		super(sqlType, scale);
 | 
			
		||||
		this.value = value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SqlParameterValue based on the given SqlParameter declaration.
 | 
			
		||||
	 * @param declaredParam the declared SqlParameter to define a value for
 | 
			
		||||
	 * @param value the value object
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameterValue(SqlParameter declaredParam, Object value) {
 | 
			
		||||
		super(declaredParam);
 | 
			
		||||
		this.value = value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the value object that this parameter value holds.
 | 
			
		||||
	 */
 | 
			
		||||
	public Object getValue() {
 | 
			
		||||
		return this.value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface to be implemented by objects that can provide SQL strings.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Typically implemented by PreparedStatementCreators, CallableStatementCreators
 | 
			
		||||
 * and StatementCallbacks that want to expose the SQL they use to create their
 | 
			
		||||
 * statements, to allow for better contextual information in case of exceptions.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 16.03.2004
 | 
			
		||||
 * @see PreparedStatementCreator
 | 
			
		||||
 * @see CallableStatementCreator
 | 
			
		||||
 * @see StatementCallback
 | 
			
		||||
 */
 | 
			
		||||
public interface SqlProvider {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQL string for this object, i.e.
 | 
			
		||||
	 * typically the SQL used for creating statements.
 | 
			
		||||
	 * @return the SQL string, or <code>null</code>
 | 
			
		||||
	 */
 | 
			
		||||
	String getSql();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a returned {@link java.sql.ResultSet} from a stored procedure call.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A {@link ResultSetExtractor}, {@link RowCallbackHandler} or {@link RowMapper}
 | 
			
		||||
 * must be provided to handle any returned rows.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Returned {@link java.sql.ResultSet ResultSets} - like all stored procedure
 | 
			
		||||
 * parameters - <b>must</b> have names.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 */
 | 
			
		||||
public class SqlReturnResultSet extends ResultSetSupportingSqlParameter {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new instance of the {@link SqlReturnResultSet} class.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param extractor ResultSetExtractor to use for parsing the {@link java.sql.ResultSet}
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlReturnResultSet(String name, ResultSetExtractor extractor) {
 | 
			
		||||
		super(name, 0, extractor);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new instance of the {@link SqlReturnResultSet} class.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param handler RowCallbackHandler to use for parsing the {@link java.sql.ResultSet}
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlReturnResultSet(String name, RowCallbackHandler handler) {
 | 
			
		||||
		super(name, 0, handler);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new instance of the {@link SqlReturnResultSet} class.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 * @param mapper RowMapper to use for parsing the {@link java.sql.ResultSet}
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlReturnResultSet(String name, RowMapper mapper) {
 | 
			
		||||
		super(name, 0, mapper);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether this parameter is an implicit return parameter used during the
 | 
			
		||||
	 * results preocessing of the CallableStatement.getMoreResults/getUpdateCount.
 | 
			
		||||
	 * <p>This implementation always returns <code>true</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isResultsParameter() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.CallableStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface to be implemented for retrieving values for more complex database-specific
 | 
			
		||||
 * types not supported by the standard <code>CallableStatement.getObject</code> method.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Implementations perform the actual work of getting the actual values. They must
 | 
			
		||||
 * implement the callback method <code>getTypeValue</code> which can throw SQLExceptions
 | 
			
		||||
 * that will be caught and translated by the calling code. This callback method has
 | 
			
		||||
 * access to the underlying Connection via the given CallableStatement object, if that
 | 
			
		||||
 * should be needed to create any database-specific objects.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see java.sql.Types
 | 
			
		||||
 * @see java.sql.CallableStatement#getObject
 | 
			
		||||
 * @see org.springframework.jdbc.object.StoredProcedure#execute(java.util.Map)
 | 
			
		||||
 */
 | 
			
		||||
public interface SqlReturnType {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constant that indicates an unknown (or unspecified) SQL type.
 | 
			
		||||
	 * Passed into setTypeValue if the original operation method does
 | 
			
		||||
	 * not specify a SQL type.
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 * @see JdbcOperations#update(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	int TYPE_UNKNOWN = Integer.MIN_VALUE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the type value from the specific object.
 | 
			
		||||
	 * @param cs the CallableStatement to operate on
 | 
			
		||||
	 * @param paramIndex the index of the parameter for which we need to set the value
 | 
			
		||||
	 * @param sqlType SQL type of the parameter we are setting
 | 
			
		||||
	 * @param typeName the type name of the parameter
 | 
			
		||||
	 * @return the target value
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered setting parameter values
 | 
			
		||||
	 * (that is, there's no need to catch SQLException)
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 * @see java.sql.CallableStatement#getObject
 | 
			
		||||
	 */
 | 
			
		||||
	Object getTypeValue(CallableStatement cs, int paramIndex, int sqlType, String typeName)
 | 
			
		||||
			throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a returned update count from a stored procedure call.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Returned update counts - like all stored procedure
 | 
			
		||||
 * parameters - <b>must</b> have names.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 */
 | 
			
		||||
public class SqlReturnUpdateCount extends SqlParameter {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new instance of the {@link SqlReturnUpdateCount} class.
 | 
			
		||||
	 * @param name name of the parameter, as used in input and output maps
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlReturnUpdateCount(String name) {
 | 
			
		||||
		super(name, Types.INTEGER);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether this parameter holds input values that should be set
 | 
			
		||||
	 * before execution even if they are <code>null</code>.
 | 
			
		||||
	 * <p>This implementation always returns <code>false</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isInputValueProvided() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether this parameter is an implicit return parameter used during the
 | 
			
		||||
	 * results preocessing of the CallableStatement.getMoreResults/getUpdateCount.
 | 
			
		||||
	 * <p>This implementation always returns <code>true</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isResultsParameter() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import javax.sql.rowset.CachedRowSet;
 | 
			
		||||
 | 
			
		||||
import com.sun.rowset.CachedRowSetImpl;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
 | 
			
		||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ResultSetExtractor implementation that returns a Spring SqlRowSet
 | 
			
		||||
 * representation for each given ResultSet.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The default implementation uses a standard JDBC CachedRowSet underneath.
 | 
			
		||||
 * This means that JDBC RowSet support needs to be available at runtime:
 | 
			
		||||
 * by default, Sun's <code>com.sun.rowset.CachedRowSetImpl</code> class is
 | 
			
		||||
 * used, which is part of JDK 1.5+ and also available separately as part of
 | 
			
		||||
 * Sun's JDBC RowSet Implementations download (rowset.jar).
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.2
 | 
			
		||||
 * @see #newCachedRowSet
 | 
			
		||||
 * @see org.springframework.jdbc.support.rowset.SqlRowSet
 | 
			
		||||
 * @see JdbcTemplate#queryForRowSet(String)
 | 
			
		||||
 * @see javax.sql.rowset.CachedRowSet
 | 
			
		||||
 */
 | 
			
		||||
public class SqlRowSetResultSetExtractor implements ResultSetExtractor {
 | 
			
		||||
 | 
			
		||||
	public Object extractData(ResultSet rs) throws SQLException {
 | 
			
		||||
		return createSqlRowSet(rs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a SqlRowSet that wraps the given ResultSet,
 | 
			
		||||
	 * representing its data in a disconnected fashion.
 | 
			
		||||
	 * <p>This implementation creates a Spring ResultSetWrappingSqlRowSet
 | 
			
		||||
	 * instance that wraps a standard JDBC CachedRowSet instance.
 | 
			
		||||
	 * Can be overridden to use a different implementation.
 | 
			
		||||
	 * @param rs the original ResultSet (connected)
 | 
			
		||||
	 * @return the disconnected SqlRowSet
 | 
			
		||||
	 * @throws SQLException if thrown by JDBC methods
 | 
			
		||||
	 * @see #newCachedRowSet
 | 
			
		||||
	 * @see org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet
 | 
			
		||||
	 */
 | 
			
		||||
	protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException {
 | 
			
		||||
		CachedRowSet rowSet = newCachedRowSet();
 | 
			
		||||
		rowSet.populate(rs);
 | 
			
		||||
		return new ResultSetWrappingSqlRowSet(rowSet);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new CachedRowSet instance, to be populated by
 | 
			
		||||
	 * the <code>createSqlRowSet</code> implementation.
 | 
			
		||||
	 * <p>The default implementation creates a new instance of
 | 
			
		||||
	 * Sun's <code>com.sun.rowset.CachedRowSetImpl</code> class,
 | 
			
		||||
	 * which is part of JDK 1.5+ and also available separately
 | 
			
		||||
	 * as part of Sun's JDBC RowSet Implementations download.
 | 
			
		||||
	 * @return a new CachedRowSet instance
 | 
			
		||||
	 * @throws SQLException if thrown by JDBC methods
 | 
			
		||||
	 * @see #createSqlRowSet
 | 
			
		||||
	 * @see com.sun.rowset.CachedRowSetImpl
 | 
			
		||||
	 */
 | 
			
		||||
	protected CachedRowSet newCachedRowSet() throws SQLException {
 | 
			
		||||
		return new CachedRowSetImpl();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface to be implemented for setting values for more complex database-specific
 | 
			
		||||
 * types not supported by the standard <code>setObject</code> method. This is
 | 
			
		||||
 * effectively an extended variant of {@link org.springframework.jdbc.support.SqlValue}.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Implementations perform the actual work of setting the actual values. They must
 | 
			
		||||
 * implement the callback method <code>setTypeValue</code> which can throw SQLExceptions
 | 
			
		||||
 * that will be caught and translated by the calling code. This callback method has
 | 
			
		||||
 * access to the underlying Connection via the given PreparedStatement object, if that
 | 
			
		||||
 * should be needed to create any database-specific objects.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see java.sql.Types
 | 
			
		||||
 * @see java.sql.PreparedStatement#setObject
 | 
			
		||||
 * @see JdbcOperations#update(String, Object[], int[])
 | 
			
		||||
 * @see org.springframework.jdbc.support.SqlValue
 | 
			
		||||
 */
 | 
			
		||||
public interface SqlTypeValue {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constant that indicates an unknown (or unspecified) SQL type.
 | 
			
		||||
	 * Passed into <code>setTypeValue</code> if the original operation method
 | 
			
		||||
	 * does not specify a SQL type.
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 * @see JdbcOperations#update(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	int TYPE_UNKNOWN = JdbcUtils.TYPE_UNKNOWN;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the type value on the given PreparedStatement.
 | 
			
		||||
	 * @param ps the PreparedStatement to work on
 | 
			
		||||
	 * @param paramIndex the index of the parameter for which we need to set the value
 | 
			
		||||
	 * @param sqlType SQL type of the parameter we are setting
 | 
			
		||||
	 * @param typeName the type name of the parameter (optional)
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered while setting parameter values
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 * @see java.sql.PreparedStatement#setObject
 | 
			
		||||
	 */
 | 
			
		||||
	void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * 
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 * 
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Statement;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic callback interface for code that operates on a JDBC Statement.
 | 
			
		||||
 * Allows to execute any number of operations on a single Statement,
 | 
			
		||||
 * for example a single <code>executeUpdate</code> call or repeated
 | 
			
		||||
 * <code>executeUpdate</code> calls with varying SQL.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Used internally by JdbcTemplate, but also useful for application code.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 16.03.2004
 | 
			
		||||
 * @see JdbcTemplate#execute(StatementCallback)
 | 
			
		||||
 */
 | 
			
		||||
public interface StatementCallback {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Gets called by <code>JdbcTemplate.execute</code> with an active JDBC
 | 
			
		||||
	 * Statement. Does not need to care about closing the Statement or the
 | 
			
		||||
	 * Connection, or about handling transactions: this will all be handled
 | 
			
		||||
	 * by Spring's JdbcTemplate.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p><b>NOTE:</b> Any ResultSets opened should be closed in finally blocks
 | 
			
		||||
	 * within the callback implementation. Spring will close the Statement
 | 
			
		||||
	 * object after the callback returned, but this does not necessarily imply
 | 
			
		||||
	 * that the ResultSet resources will be closed: the Statement objects might
 | 
			
		||||
	 * get pooled by the connection pool, with <code>close</code> calls only
 | 
			
		||||
	 * returning the object to the pool but not physically closing the resources.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>If called without a thread-bound JDBC transaction (initiated by
 | 
			
		||||
	 * DataSourceTransactionManager), the code will simply get executed on the
 | 
			
		||||
	 * JDBC connection with its transactional semantics. If JdbcTemplate is
 | 
			
		||||
	 * configured to use a JTA-aware DataSource, the JDBC connection and thus
 | 
			
		||||
	 * the callback code will be transactional if a JTA transaction is active.
 | 
			
		||||
	 *
 | 
			
		||||
	 * <p>Allows for returning a result object created within the callback, i.e.
 | 
			
		||||
	 * a domain object or a collection of domain objects. Note that there's
 | 
			
		||||
	 * special support for single step actions: see JdbcTemplate.queryForObject etc.
 | 
			
		||||
	 * A thrown RuntimeException is treated as application exception, it gets
 | 
			
		||||
	 * propagated to the caller of the template.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param stmt active JDBC Statement
 | 
			
		||||
	 * @return a result object, or <code>null</code> if none
 | 
			
		||||
	 * @throws SQLException if thrown by a JDBC method, to be auto-converted
 | 
			
		||||
	 * to a DataAccessException by a SQLExceptionTranslator
 | 
			
		||||
	 * @throws DataAccessException in case of custom exceptions
 | 
			
		||||
	 * @see JdbcTemplate#queryForObject(String, Class)
 | 
			
		||||
	 * @see JdbcTemplate#queryForRowSet(String)
 | 
			
		||||
	 */
 | 
			
		||||
	Object doInStatement(Statement stmt) throws SQLException, DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,409 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core;
 | 
			
		||||
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
import java.sql.Blob;
 | 
			
		||||
import java.sql.Clob;
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.support.SqlValue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utility methods for PreparedStatementSetter/Creator and CallableStatementCreator
 | 
			
		||||
 * implementations, providing sophisticated parameter management (including support
 | 
			
		||||
 * for LOB values).
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Used by PreparedStatementCreatorFactory and CallableStatementCreatorFactory,
 | 
			
		||||
 * but also available for direct use in custom setter/creator implementations.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see PreparedStatementSetter
 | 
			
		||||
 * @see PreparedStatementCreator
 | 
			
		||||
 * @see CallableStatementCreator
 | 
			
		||||
 * @see PreparedStatementCreatorFactory
 | 
			
		||||
 * @see CallableStatementCreatorFactory
 | 
			
		||||
 * @see SqlParameter
 | 
			
		||||
 * @see SqlTypeValue
 | 
			
		||||
 * @see org.springframework.jdbc.core.support.SqlLobValue
 | 
			
		||||
 */
 | 
			
		||||
public abstract class StatementCreatorUtils {
 | 
			
		||||
 | 
			
		||||
	private static final Log logger = LogFactory.getLog(StatementCreatorUtils.class);
 | 
			
		||||
 | 
			
		||||
	private static Map javaTypeToSqlTypeMap = new HashMap(32);
 | 
			
		||||
 | 
			
		||||
	static {
 | 
			
		||||
		/* JDBC 3.0 only - not compatible with e.g. MySQL at present
 | 
			
		||||
		javaTypeToSqlTypeMap.put(boolean.class, new Integer(Types.BOOLEAN));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Boolean.class, new Integer(Types.BOOLEAN));
 | 
			
		||||
		*/
 | 
			
		||||
		javaTypeToSqlTypeMap.put(byte.class, new Integer(Types.TINYINT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Byte.class, new Integer(Types.TINYINT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(short.class, new Integer(Types.SMALLINT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Short.class, new Integer(Types.SMALLINT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(int.class, new Integer(Types.INTEGER));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Integer.class, new Integer(Types.INTEGER));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(long.class, new Integer(Types.BIGINT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Long.class, new Integer(Types.BIGINT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(BigInteger.class, new Integer(Types.BIGINT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(float.class, new Integer(Types.FLOAT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Float.class, new Integer(Types.FLOAT));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(double.class, new Integer(Types.DOUBLE));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Double.class, new Integer(Types.DOUBLE));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(BigDecimal.class, new Integer(Types.DECIMAL));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(java.sql.Date.class, new Integer(Types.DATE));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(java.sql.Time.class, new Integer(Types.TIME));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(java.sql.Timestamp.class, new Integer(Types.TIMESTAMP));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Blob.class, new Integer(Types.BLOB));
 | 
			
		||||
		javaTypeToSqlTypeMap.put(Clob.class, new Integer(Types.CLOB));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Derive a default SQL type from the given Java type.
 | 
			
		||||
	 * @param javaType the Java type to translate
 | 
			
		||||
	 * @return the corresponding SQL type, or <code>null</code> if none found
 | 
			
		||||
	 */
 | 
			
		||||
	public static int javaTypeToSqlParameterType(Class javaType) {
 | 
			
		||||
		Integer sqlType = (Integer) javaTypeToSqlTypeMap.get(javaType);
 | 
			
		||||
		if (sqlType != null) {
 | 
			
		||||
			return sqlType.intValue();
 | 
			
		||||
		}
 | 
			
		||||
		if (Number.class.isAssignableFrom(javaType)) {
 | 
			
		||||
			return Types.NUMERIC;
 | 
			
		||||
		}
 | 
			
		||||
		if (isStringValue(javaType)) {
 | 
			
		||||
			return Types.VARCHAR;
 | 
			
		||||
		}
 | 
			
		||||
		if (isDateValue(javaType) || Calendar.class.isAssignableFrom(javaType)) {
 | 
			
		||||
			return Types.TIMESTAMP;
 | 
			
		||||
		}
 | 
			
		||||
		return SqlTypeValue.TYPE_UNKNOWN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the value for a parameter. The method used is based on the SQL type
 | 
			
		||||
	 * of the parameter and we can handle complex types like arrays and LOBs.
 | 
			
		||||
	 * @param ps the prepared statement or callable statement
 | 
			
		||||
	 * @param paramIndex index of the parameter we are setting
 | 
			
		||||
	 * @param param the parameter as it is declared including type
 | 
			
		||||
	 * @param inValue the value to set
 | 
			
		||||
	 * @throws SQLException if thrown by PreparedStatement methods
 | 
			
		||||
	 */
 | 
			
		||||
	public static void setParameterValue(
 | 
			
		||||
	    PreparedStatement ps, int paramIndex, SqlParameter param, Object inValue)
 | 
			
		||||
	    throws SQLException {
 | 
			
		||||
 | 
			
		||||
		setParameterValueInternal(ps, paramIndex, param.getSqlType(), param.getTypeName(), param.getScale(), inValue);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the value for a parameter. The method used is based on the SQL type
 | 
			
		||||
	 * of the parameter and we can handle complex types like arrays and LOBs.
 | 
			
		||||
	 * @param ps the prepared statement or callable statement
 | 
			
		||||
	 * @param paramIndex index of the parameter we are setting
 | 
			
		||||
	 * @param sqlType the SQL type of the parameter
 | 
			
		||||
	 * @param inValue the value to set (plain value or a SqlTypeValue)
 | 
			
		||||
	 * @throws SQLException if thrown by PreparedStatement methods
 | 
			
		||||
	 * @see SqlTypeValue
 | 
			
		||||
	 */
 | 
			
		||||
	public static void setParameterValue(
 | 
			
		||||
	    PreparedStatement ps, int paramIndex, int sqlType, Object inValue)
 | 
			
		||||
	    throws SQLException {
 | 
			
		||||
 | 
			
		||||
		setParameterValueInternal(ps, paramIndex, sqlType, null, null, inValue);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the value for a parameter. The method used is based on the SQL type
 | 
			
		||||
	 * of the parameter and we can handle complex types like arrays and LOBs.
 | 
			
		||||
	 * @param ps the prepared statement or callable statement
 | 
			
		||||
	 * @param paramIndex index of the parameter we are setting
 | 
			
		||||
	 * @param sqlType the SQL type of the parameter
 | 
			
		||||
	 * @param typeName the type name of the parameter
 | 
			
		||||
	 * (optional, only used for SQL NULL and SqlTypeValue)
 | 
			
		||||
	 * @param inValue the value to set (plain value or a SqlTypeValue)
 | 
			
		||||
	 * @throws SQLException if thrown by PreparedStatement methods
 | 
			
		||||
	 * @see SqlTypeValue
 | 
			
		||||
	 */
 | 
			
		||||
	public static void setParameterValue(
 | 
			
		||||
	    PreparedStatement ps, int paramIndex, int sqlType, String typeName, Object inValue)
 | 
			
		||||
	    throws SQLException {
 | 
			
		||||
 | 
			
		||||
		setParameterValueInternal(ps, paramIndex, sqlType, typeName, null, inValue);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the value for a parameter. The method used is based on the SQL type
 | 
			
		||||
	 * of the parameter and we can handle complex types like arrays and LOBs.
 | 
			
		||||
	 * @param ps the prepared statement or callable statement
 | 
			
		||||
	 * @param paramIndex index of the parameter we are setting
 | 
			
		||||
	 * @param sqlType the SQL type of the parameter
 | 
			
		||||
	 * @param typeName the type name of the parameter
 | 
			
		||||
	 * (optional, only used for SQL NULL and SqlTypeValue)
 | 
			
		||||
	 * @param scale the number of digits after the decimal point
 | 
			
		||||
	 * (for DECIMAL and NUMERIC types)
 | 
			
		||||
	 * @param inValue the value to set (plain value or a SqlTypeValue)
 | 
			
		||||
	 * @throws SQLException if thrown by PreparedStatement methods
 | 
			
		||||
	 * @see SqlTypeValue
 | 
			
		||||
	 */
 | 
			
		||||
	private static void setParameterValueInternal(
 | 
			
		||||
	    PreparedStatement ps, int paramIndex, int sqlType, String typeName, Integer scale, Object inValue)
 | 
			
		||||
	    throws SQLException {
 | 
			
		||||
 | 
			
		||||
		String typeNameToUse = typeName;
 | 
			
		||||
		int sqlTypeToUse = sqlType;
 | 
			
		||||
		Object inValueToUse = inValue;
 | 
			
		||||
 | 
			
		||||
		// override type info?
 | 
			
		||||
		if (inValue instanceof SqlParameterValue) {
 | 
			
		||||
			SqlParameterValue parameterValue = (SqlParameterValue) inValue;
 | 
			
		||||
			if (logger.isDebugEnabled()) {
 | 
			
		||||
				logger.debug("Overriding typeinfo with runtime info from SqlParameterValue: column index " + paramIndex +
 | 
			
		||||
						", SQL type " + parameterValue.getSqlType() +
 | 
			
		||||
						", Type name " + parameterValue.getTypeName());
 | 
			
		||||
			}
 | 
			
		||||
			if (parameterValue.getSqlType() != SqlTypeValue.TYPE_UNKNOWN) {
 | 
			
		||||
				sqlTypeToUse = parameterValue.getSqlType();
 | 
			
		||||
			}
 | 
			
		||||
			if (parameterValue.getTypeName() != null) {
 | 
			
		||||
				typeNameToUse = parameterValue.getTypeName();
 | 
			
		||||
			}
 | 
			
		||||
			inValueToUse = parameterValue.getValue();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (logger.isTraceEnabled()) {
 | 
			
		||||
			logger.trace("Setting SQL statement parameter value: column index " + paramIndex +
 | 
			
		||||
					", parameter value [" + inValueToUse +
 | 
			
		||||
					"], value class [" + (inValueToUse != null ? inValueToUse.getClass().getName() : "null") +
 | 
			
		||||
					"], SQL type " + (sqlTypeToUse == SqlTypeValue.TYPE_UNKNOWN ? "unknown" : Integer.toString(sqlTypeToUse)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (inValueToUse == null) {
 | 
			
		||||
			setNull(ps, paramIndex, sqlTypeToUse, typeNameToUse);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			setValue(ps, paramIndex, sqlTypeToUse, typeNameToUse, scale, inValueToUse);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static void setNull(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException {
 | 
			
		||||
		if (sqlType == SqlTypeValue.TYPE_UNKNOWN) {
 | 
			
		||||
			boolean useSetObject = false;
 | 
			
		||||
			sqlType = Types.NULL;
 | 
			
		||||
			try {
 | 
			
		||||
				DatabaseMetaData dbmd = ps.getConnection().getMetaData();
 | 
			
		||||
				String databaseProductName = dbmd.getDatabaseProductName();
 | 
			
		||||
				String jdbcDriverName = dbmd.getDriverName();
 | 
			
		||||
				if (databaseProductName.startsWith("Informix") ||
 | 
			
		||||
						jdbcDriverName.startsWith("Microsoft SQL Server")) {
 | 
			
		||||
					useSetObject = true;
 | 
			
		||||
				}
 | 
			
		||||
				else if (databaseProductName.startsWith("DB2") ||
 | 
			
		||||
						jdbcDriverName.startsWith("jConnect") ||
 | 
			
		||||
						jdbcDriverName.startsWith("SQLServer")||
 | 
			
		||||
						jdbcDriverName.startsWith("Apache Derby Embedded")) {
 | 
			
		||||
					sqlType = Types.VARCHAR;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch (Throwable ex) {
 | 
			
		||||
				logger.debug("Could not check database or driver name", ex);
 | 
			
		||||
			}
 | 
			
		||||
			if (useSetObject) {
 | 
			
		||||
				ps.setObject(paramIndex, null);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ps.setNull(paramIndex, sqlType);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (typeName != null) {
 | 
			
		||||
			ps.setNull(paramIndex, sqlType, typeName);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			ps.setNull(paramIndex, sqlType);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static void setValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName,
 | 
			
		||||
			Integer scale, Object inValue) throws SQLException {
 | 
			
		||||
 | 
			
		||||
		if (inValue instanceof SqlTypeValue) {
 | 
			
		||||
			((SqlTypeValue) inValue).setTypeValue(ps, paramIndex, sqlType, typeName);
 | 
			
		||||
		}
 | 
			
		||||
		else if (inValue instanceof SqlValue) {
 | 
			
		||||
			((SqlValue) inValue).setValue(ps, paramIndex);
 | 
			
		||||
		}
 | 
			
		||||
		else if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR ||
 | 
			
		||||
				(sqlType == Types.CLOB && isStringValue(inValue.getClass()))) {
 | 
			
		||||
			ps.setString(paramIndex, inValue.toString());
 | 
			
		||||
		}
 | 
			
		||||
		else if (sqlType == Types.DECIMAL || sqlType == Types.NUMERIC) {
 | 
			
		||||
			if (inValue instanceof BigDecimal) {
 | 
			
		||||
				ps.setBigDecimal(paramIndex, (BigDecimal) inValue);
 | 
			
		||||
			}
 | 
			
		||||
			else if (scale != null) {
 | 
			
		||||
				ps.setObject(paramIndex, inValue, sqlType, scale.intValue());
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ps.setObject(paramIndex, inValue, sqlType);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (sqlType == Types.DATE) {
 | 
			
		||||
			if (inValue instanceof java.util.Date) {
 | 
			
		||||
				if (inValue instanceof java.sql.Date) {
 | 
			
		||||
					ps.setDate(paramIndex, (java.sql.Date) inValue);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					ps.setDate(paramIndex, new java.sql.Date(((java.util.Date) inValue).getTime()));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (inValue instanceof Calendar) {
 | 
			
		||||
				Calendar cal = (Calendar) inValue;
 | 
			
		||||
				ps.setDate(paramIndex, new java.sql.Date(cal.getTime().getTime()), cal);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ps.setObject(paramIndex, inValue, Types.DATE);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (sqlType == Types.TIME) {
 | 
			
		||||
			if (inValue instanceof java.util.Date) {
 | 
			
		||||
				if (inValue instanceof java.sql.Time) {
 | 
			
		||||
					ps.setTime(paramIndex, (java.sql.Time) inValue);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					ps.setTime(paramIndex, new java.sql.Time(((java.util.Date) inValue).getTime()));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (inValue instanceof Calendar) {
 | 
			
		||||
				Calendar cal = (Calendar) inValue;
 | 
			
		||||
				ps.setTime(paramIndex, new java.sql.Time(cal.getTime().getTime()), cal);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ps.setObject(paramIndex, inValue, Types.TIME);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (sqlType == Types.TIMESTAMP) {
 | 
			
		||||
			if (inValue instanceof java.util.Date) {
 | 
			
		||||
				if (inValue instanceof java.sql.Timestamp) {
 | 
			
		||||
					ps.setTimestamp(paramIndex, (java.sql.Timestamp) inValue);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime()));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (inValue instanceof Calendar) {
 | 
			
		||||
				Calendar cal = (Calendar) inValue;
 | 
			
		||||
				ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				ps.setObject(paramIndex, inValue, Types.TIMESTAMP);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (sqlType == SqlTypeValue.TYPE_UNKNOWN) {
 | 
			
		||||
			if (isStringValue(inValue.getClass())) {
 | 
			
		||||
				ps.setString(paramIndex, inValue.toString());
 | 
			
		||||
			}
 | 
			
		||||
			else if (isDateValue(inValue.getClass())) {
 | 
			
		||||
				ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime()));
 | 
			
		||||
			}
 | 
			
		||||
			else if (inValue instanceof Calendar) {
 | 
			
		||||
				Calendar cal = (Calendar) inValue;
 | 
			
		||||
				ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				// Fall back to generic setObject call without SQL type specified.
 | 
			
		||||
				ps.setObject(paramIndex, inValue);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			// Fall back to generic setObject call with SQL type specified.
 | 
			
		||||
			ps.setObject(paramIndex, inValue, sqlType);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether the given value can be treated as a String value.
 | 
			
		||||
	 */
 | 
			
		||||
	private static boolean isStringValue(Class inValueType) {
 | 
			
		||||
		// Consider any CharSequence (including JDK 1.5's StringBuilder) as String.
 | 
			
		||||
		return (CharSequence.class.isAssignableFrom(inValueType) ||
 | 
			
		||||
				StringWriter.class.isAssignableFrom(inValueType));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether the given value is a <code>java.util.Date</code>
 | 
			
		||||
	 * (but not one of the JDBC-specific subclasses).
 | 
			
		||||
	 */
 | 
			
		||||
	private static boolean isDateValue(Class inValueType) {
 | 
			
		||||
		return (java.util.Date.class.isAssignableFrom(inValueType) &&
 | 
			
		||||
				!(java.sql.Date.class.isAssignableFrom(inValueType) ||
 | 
			
		||||
						java.sql.Time.class.isAssignableFrom(inValueType) ||
 | 
			
		||||
						java.sql.Timestamp.class.isAssignableFrom(inValueType)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Clean up all resources held by parameter values which were passed to an
 | 
			
		||||
	 * execute method. This is for example important for closing LOB values.
 | 
			
		||||
	 * @param paramValues parameter values supplied. May be <code>null</code>.
 | 
			
		||||
	 * @see DisposableSqlTypeValue#cleanup()
 | 
			
		||||
	 * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup()
 | 
			
		||||
	 */
 | 
			
		||||
	public static void cleanupParameters(Object[] paramValues) {
 | 
			
		||||
		if (paramValues != null) {
 | 
			
		||||
			cleanupParameters(Arrays.asList(paramValues));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Clean up all resources held by parameter values which were passed to an
 | 
			
		||||
	 * execute method. This is for example important for closing LOB values.
 | 
			
		||||
	 * @param paramValues parameter values supplied. May be <code>null</code>.
 | 
			
		||||
	 * @see DisposableSqlTypeValue#cleanup()
 | 
			
		||||
	 * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup()
 | 
			
		||||
	 */
 | 
			
		||||
	public static void cleanupParameters(Collection paramValues) {
 | 
			
		||||
		if (paramValues != null) {
 | 
			
		||||
			for (Iterator it = paramValues.iterator(); it.hasNext();) {
 | 
			
		||||
				Object inValue = it.next();
 | 
			
		||||
				if (inValue instanceof DisposableSqlTypeValue) {
 | 
			
		||||
					((DisposableSqlTypeValue) inValue).cleanup();
 | 
			
		||||
				}
 | 
			
		||||
				else if (inValue instanceof SqlValue) {
 | 
			
		||||
					((SqlValue) inValue).cleanup();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,589 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.jdbc.core.RowMapper;
 | 
			
		||||
import org.springframework.jdbc.core.SqlOutParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlReturnResultSet;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameterValue;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to manage context metadata used for the configuration and execution of the call.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class CallMetaDataContext {
 | 
			
		||||
 | 
			
		||||
	/** Logger available to subclasses */
 | 
			
		||||
	protected final Log logger = LogFactory.getLog(getClass());
 | 
			
		||||
 | 
			
		||||
	/** name of procedure to call **/
 | 
			
		||||
	private String procedureName;
 | 
			
		||||
 | 
			
		||||
	/** name of catalog for call **/
 | 
			
		||||
	private String catalogName;
 | 
			
		||||
 | 
			
		||||
	/** name of schema for call **/
 | 
			
		||||
	private String schemaName;
 | 
			
		||||
 | 
			
		||||
	/** List of SqlParameter objects to be used in call execution */
 | 
			
		||||
	private List<SqlParameter> callParameters = new ArrayList<SqlParameter>();
 | 
			
		||||
 | 
			
		||||
	/** name to use for the return value in the output map */
 | 
			
		||||
	private String functionReturnName = "return";
 | 
			
		||||
 | 
			
		||||
	/** Set of in parameter names to exclude use for any not listed */
 | 
			
		||||
	private Set<String> limitedInParameterNames = new HashSet<String>();
 | 
			
		||||
 | 
			
		||||
	/** List of SqlParameter names for out parameters */
 | 
			
		||||
	private List<String> outParameterNames = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
	/** should we access call parameter meta data info or not */
 | 
			
		||||
	private boolean accessCallParameterMetaData = true;
 | 
			
		||||
 | 
			
		||||
	/** indicates whether this is a procedure or a function **/
 | 
			
		||||
	private boolean function;
 | 
			
		||||
 | 
			
		||||
	/** indicates whether this procedure's return value should be included  **/
 | 
			
		||||
	private boolean returnValueRequired;
 | 
			
		||||
 | 
			
		||||
	/** the provider of call meta data */
 | 
			
		||||
	private CallMetaDataProvider metaDataProvider;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the name used for the return value of the function.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setFunctionReturnName(String functionReturnName) {
 | 
			
		||||
		this.functionReturnName = functionReturnName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name used for the return value of the function.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getFunctionReturnName() {
 | 
			
		||||
		return this.functionReturnName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify a limited set of in parameters to be used.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setLimitedInParameterNames(Set<String> limitedInParameterNames) {
 | 
			
		||||
		this.limitedInParameterNames = limitedInParameterNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get a limited set of in parameters to be used.
 | 
			
		||||
	 */
 | 
			
		||||
	public Set<String> getLimitedInParameterNames() {
 | 
			
		||||
		return this.limitedInParameterNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the names of the out parameters.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setOutParameterNames(List<String> outParameterNames) {
 | 
			
		||||
		this.outParameterNames = outParameterNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get a list of the out parameter names.
 | 
			
		||||
	 */
 | 
			
		||||
	public List<String> getOutParameterNames() {
 | 
			
		||||
		return this.outParameterNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the name of the procedure.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setProcedureName(String procedureName) {
 | 
			
		||||
		this.procedureName = procedureName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the procedure.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getProcedureName() {
 | 
			
		||||
		return this.procedureName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the name of the catalog.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setCatalogName(String catalogName) {
 | 
			
		||||
		this.catalogName = catalogName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the catalog.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getCatalogName() {
 | 
			
		||||
		return this.catalogName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Secify the name of the schema.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSchemaName(String schemaName) {
 | 
			
		||||
		this.schemaName = schemaName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the schema.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSchemaName() {
 | 
			
		||||
		return this.schemaName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether this call is a function call.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setFunction(boolean function) {
 | 
			
		||||
		this.function = function;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether this call is a function call.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isFunction() {
 | 
			
		||||
		return this.function;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether a return value is required.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setReturnValueRequired(boolean returnValueRequired) {
 | 
			
		||||
		this.returnValueRequired = returnValueRequired;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether a return value is required.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isReturnValueRequired() {
 | 
			
		||||
		return this.returnValueRequired;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether call parameter metadata should be accessed.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setAccessCallParameterMetaData(boolean accessCallParameterMetaData) {
 | 
			
		||||
		this.accessCallParameterMetaData = accessCallParameterMetaData;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether call parameter metadata should be accessed.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isAccessCallParameterMetaData() {
 | 
			
		||||
		return this.accessCallParameterMetaData;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided
 | 
			
		||||
	 * by the JDBC driver used for the database in use.
 | 
			
		||||
	 * @param parameterName the name of the parameter (also used as the name of the List returned in the output)
 | 
			
		||||
	 * @param rowMapper a RowMapper implementation used to map the data retuned in the result set
 | 
			
		||||
	 * @return the appropriate SqlParameter
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper rowMapper) {
 | 
			
		||||
		if (this.metaDataProvider.isReturnResultSetSupported()) {
 | 
			
		||||
			return new SqlReturnResultSet(parameterName, rowMapper);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (this.metaDataProvider.isRefCursorSupported()) {
 | 
			
		||||
				return new SqlOutParameter(parameterName, this.metaDataProvider.getRefCursorSqlType(), rowMapper);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException("Return of a ResultSet from a stored procedure is not supported.");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the single out parameter for this call.  If there are multiple parameters then the name of
 | 
			
		||||
	 * the first one is returned.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getScalarOutParameterName() {
 | 
			
		||||
		if (isFunction()) {
 | 
			
		||||
			return this.functionReturnName;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (this.outParameterNames.size() > 1) {
 | 
			
		||||
				logger.warn("Accessing single output value when procedure has more than one output parameter");
 | 
			
		||||
			}
 | 
			
		||||
			return (this.outParameterNames.size() > 0 ? this.outParameterNames.get(0) : null);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the List of SqlParameter objects to be used in call execution
 | 
			
		||||
	 */
 | 
			
		||||
	public List<SqlParameter> getCallParameters() {
 | 
			
		||||
		return this.callParameters;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize this class with metadata from the database 
 | 
			
		||||
	 * @param dataSource the DataSource used to retrieve metadata
 | 
			
		||||
	 */
 | 
			
		||||
	public void initializeMetaData(DataSource dataSource) {
 | 
			
		||||
		this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Process the list of parameters provided and if procedure column metedata is used the
 | 
			
		||||
	 * parameters will be matched against the metadata information and any missing ones will
 | 
			
		||||
	 * be automatically included
 | 
			
		||||
	 * @param parameters the list of parameters to use as a base
 | 
			
		||||
	 */
 | 
			
		||||
	public void processParameters(List<SqlParameter> parameters) {
 | 
			
		||||
		this.callParameters = reconcileParameters(parameters);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Reconcile the provided parameters with available metadata and add new ones where appropriate
 | 
			
		||||
	 */
 | 
			
		||||
	private List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
 | 
			
		||||
		final List<SqlParameter> declaredReturnParameters = new ArrayList<SqlParameter>();
 | 
			
		||||
		final Map<String, SqlParameter> declaredParameters = new LinkedHashMap<String, SqlParameter>();
 | 
			
		||||
		boolean returnDeclared = false;
 | 
			
		||||
		List<String> outParameterNames = new ArrayList<String>();
 | 
			
		||||
		List<String> metaDataParameterNames = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
		// get the names of the meta data parameters
 | 
			
		||||
		for (CallParameterMetaData meta : metaDataProvider.getCallParameterMetaData()) {
 | 
			
		||||
			if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
 | 
			
		||||
				metaDataParameterNames.add(meta.getParameterName().toLowerCase());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Separate implicit return parameters from explicit parameters...
 | 
			
		||||
		for (SqlParameter parameter : parameters) {
 | 
			
		||||
			if (parameter.isResultsParameter()) {
 | 
			
		||||
				declaredReturnParameters.add(parameter);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameter.getName()).toLowerCase();
 | 
			
		||||
				declaredParameters.put(parameterNameToMatch, parameter);
 | 
			
		||||
				if (parameter instanceof SqlOutParameter) {
 | 
			
		||||
					outParameterNames.add(parameter.getName());
 | 
			
		||||
					if (this.isFunction() && !metaDataParameterNames.contains(parameterNameToMatch)) {
 | 
			
		||||
						if (!returnDeclared) {
 | 
			
		||||
							if (logger.isDebugEnabled()) {
 | 
			
		||||
								logger.debug("Using declared out parameter '" + parameter.getName() + "' for function return value");
 | 
			
		||||
							}
 | 
			
		||||
							this.setFunctionReturnName(parameter.getName());
 | 
			
		||||
							returnDeclared = true;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		this.setOutParameterNames(outParameterNames);
 | 
			
		||||
 | 
			
		||||
		final List<SqlParameter> workParameters = new ArrayList<SqlParameter>();
 | 
			
		||||
		workParameters.addAll(declaredReturnParameters);
 | 
			
		||||
 | 
			
		||||
		if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
 | 
			
		||||
			workParameters.addAll(declaredParameters.values());
 | 
			
		||||
			return workParameters;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Map<String, String> limitedInParamNamesMap = new HashMap<String, String>(this.limitedInParameterNames.size());
 | 
			
		||||
		for (String limitedParameterName : this.limitedInParameterNames) {
 | 
			
		||||
			limitedInParamNamesMap.put(
 | 
			
		||||
					this.metaDataProvider.parameterNameToUse(limitedParameterName).toLowerCase(), limitedParameterName);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (CallParameterMetaData meta : metaDataProvider.getCallParameterMetaData()) {
 | 
			
		||||
			String parNameToCheck = null;
 | 
			
		||||
			if (meta.getParameterName() != null) {
 | 
			
		||||
				parNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase();
 | 
			
		||||
			}
 | 
			
		||||
			String parNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName());
 | 
			
		||||
			if (declaredParameters.containsKey(parNameToCheck) ||
 | 
			
		||||
					(meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
 | 
			
		||||
				SqlParameter parameter;
 | 
			
		||||
				if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
 | 
			
		||||
					parameter = declaredParameters.get(this.getFunctionReturnName());
 | 
			
		||||
					if (parameter == null && this.getOutParameterNames().size() > 0) {
 | 
			
		||||
						parameter = declaredParameters.get(this.getOutParameterNames().get(0).toLowerCase());
 | 
			
		||||
					}
 | 
			
		||||
					if (parameter == null) {
 | 
			
		||||
						throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
								"Unable to locate declared parameter for function return value - " +
 | 
			
		||||
										" add an SqlOutParameter with name \"" + getFunctionReturnName() +"\"");
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						this.setFunctionReturnName(parameter.getName());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					parameter = declaredParameters.get(parNameToCheck);
 | 
			
		||||
				}
 | 
			
		||||
				if (parameter != null) {
 | 
			
		||||
					workParameters.add(parameter);
 | 
			
		||||
					if (logger.isDebugEnabled()) {
 | 
			
		||||
						logger.debug("Using declared parameter for: " +
 | 
			
		||||
								(parNameToUse == null ? getFunctionReturnName() : parNameToUse));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
 | 
			
		||||
					if (!isFunction() && !isReturnValueRequired() &&
 | 
			
		||||
							this.metaDataProvider.byPassReturnParameter(meta.getParameterName())) {
 | 
			
		||||
						if (logger.isDebugEnabled()) {
 | 
			
		||||
							logger.debug("Bypassing metadata return parameter for: " + meta.getParameterName());
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						String returnNameToUse =
 | 
			
		||||
								( meta.getParameterName() == null || meta.getParameterName().length() < 1 ) ? 
 | 
			
		||||
										this.getFunctionReturnName() : parNameToUse;
 | 
			
		||||
						workParameters.add(new SqlOutParameter(returnNameToUse, meta.getSqlType()));
 | 
			
		||||
						if (this.isFunction())
 | 
			
		||||
							outParameterNames.add(returnNameToUse);
 | 
			
		||||
						if (logger.isDebugEnabled()) {
 | 
			
		||||
							logger.debug("Added metadata return parameter for: " + returnNameToUse);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
 | 
			
		||||
						workParameters.add(this.metaDataProvider.createDefaultOutParameter(parNameToUse, meta));
 | 
			
		||||
						outParameterNames.add(parNameToUse);
 | 
			
		||||
						if (logger.isDebugEnabled()) {
 | 
			
		||||
							logger.debug("Added metadata out parameter for: " + parNameToUse);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
 | 
			
		||||
						workParameters.add(this.metaDataProvider.createDefaultInOutParameter(parNameToUse, meta));
 | 
			
		||||
						outParameterNames.add(parNameToUse);
 | 
			
		||||
						if (logger.isDebugEnabled()) {
 | 
			
		||||
							logger.debug("Added metadata in out parameter for: " + parNameToUse);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						if (this.limitedInParameterNames.size() == 0 ||
 | 
			
		||||
								limitedInParamNamesMap.containsKey(parNameToUse.toLowerCase())) {
 | 
			
		||||
							workParameters.add(this.metaDataProvider.createDefaultInParameter(parNameToUse, meta));
 | 
			
		||||
							if (logger.isDebugEnabled()) {
 | 
			
		||||
								logger.debug("Added metadata in parameter for: " + parNameToUse);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							if (logger.isDebugEnabled()) {
 | 
			
		||||
								logger.debug("Limited set of parameters " + limitedInParamNamesMap.keySet() +
 | 
			
		||||
										" skipped parameter for: " + parNameToUse);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return workParameters;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match input parameter values with the parameters declared to be used in the call.
 | 
			
		||||
	 * @param parameterSource the input values
 | 
			
		||||
	 * @return a Map containing the matched parameter names with the value taken from the input
 | 
			
		||||
	 */
 | 
			
		||||
	public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) {
 | 
			
		||||
		// For parameter source lookups we need to provide case-insensitive lookup support
 | 
			
		||||
		// since the database metadata is not necessarily providing case sensitive parameter names.
 | 
			
		||||
		Map caseInsensitiveParameterNames =
 | 
			
		||||
				SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource);
 | 
			
		||||
 | 
			
		||||
		Map<String, String> callParameterNames = new HashMap<String, String>(this.callParameters.size());
 | 
			
		||||
		Map<String, Object> matchedParameters = new HashMap<String, Object>(this.callParameters.size());
 | 
			
		||||
		for (SqlParameter parameter : this.callParameters) {
 | 
			
		||||
			if (parameter.isInputValueProvided()) {
 | 
			
		||||
				String parameterName = parameter.getName();
 | 
			
		||||
				String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
 | 
			
		||||
				if (parameterNameToMatch != null) {
 | 
			
		||||
					callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
 | 
			
		||||
				}
 | 
			
		||||
				if (parameterName != null) {
 | 
			
		||||
					if (parameterSource.hasValue(parameterName)) {
 | 
			
		||||
						matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, parameterName));
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						String lowerCaseName = parameterName.toLowerCase();
 | 
			
		||||
						if (parameterSource.hasValue(lowerCaseName)) {
 | 
			
		||||
							matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, lowerCaseName));
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							String propertyName = JdbcUtils.convertUnderscoreNameToPropertyName(parameterName);
 | 
			
		||||
							if (parameterSource.hasValue(propertyName)) {
 | 
			
		||||
								matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, propertyName));
 | 
			
		||||
							}
 | 
			
		||||
							else {
 | 
			
		||||
								if (caseInsensitiveParameterNames.containsKey(lowerCaseName)) {
 | 
			
		||||
									String sourceName = (String) caseInsensitiveParameterNames.get(lowerCaseName);
 | 
			
		||||
									matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, sourceName));
 | 
			
		||||
								}
 | 
			
		||||
								else {
 | 
			
		||||
									logger.warn("Unable to locate the corresponding parameter value for '" + parameterName +
 | 
			
		||||
											"' within the parameter values provided: " + caseInsensitiveParameterNames.values());
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Matching " + caseInsensitiveParameterNames.values() + " with " + callParameterNames.values());
 | 
			
		||||
			logger.debug("Found match for " + matchedParameters.keySet());
 | 
			
		||||
		}
 | 
			
		||||
		return matchedParameters;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match input parameter values with the parameters declared to be used in the call.
 | 
			
		||||
	 * @param inParameters the input values
 | 
			
		||||
	 * @return a Map containing the matched parameter names with the value taken from the input
 | 
			
		||||
	 */
 | 
			
		||||
	public Map<String, Object> matchInParameterValuesWithCallParameters(Map<String, Object> inParameters) {
 | 
			
		||||
		if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
 | 
			
		||||
			return inParameters;
 | 
			
		||||
		}
 | 
			
		||||
		Map<String, String> callParameterNames = new HashMap<String, String>(this.callParameters.size());
 | 
			
		||||
		for (SqlParameter parameter : this.callParameters) {
 | 
			
		||||
			if (parameter.isInputValueProvided()) {
 | 
			
		||||
				String parameterName =  parameter.getName();
 | 
			
		||||
				String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
 | 
			
		||||
				if (parameterNameToMatch != null) {
 | 
			
		||||
					callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		Map<String, Object> matchedParameters = new HashMap<String, Object>(inParameters.size());
 | 
			
		||||
		for (String parameterName : inParameters.keySet()) {
 | 
			
		||||
			String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
 | 
			
		||||
			String callParameterName = callParameterNames.get(parameterNameToMatch.toLowerCase());
 | 
			
		||||
			if (callParameterName == null) {
 | 
			
		||||
				if (logger.isDebugEnabled()) {
 | 
			
		||||
					Object value = inParameters.get(parameterName);
 | 
			
		||||
					if (value instanceof SqlParameterValue) {
 | 
			
		||||
						value = ((SqlParameterValue)value).getValue();
 | 
			
		||||
					}
 | 
			
		||||
					if (value != null) {
 | 
			
		||||
						logger.debug("Unable to locate the corresponding IN or IN-OUT parameter for \"" + parameterName +
 | 
			
		||||
								"\" in the parameters used: " + callParameterNames.keySet());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				matchedParameters.put(callParameterName, inParameters.get(parameterName));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (matchedParameters.size() < callParameterNames.size()) {
 | 
			
		||||
			for (String parameterName : callParameterNames.keySet()) {
 | 
			
		||||
				String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
 | 
			
		||||
				String callParameterName = callParameterNames.get(parameterNameToMatch.toLowerCase());
 | 
			
		||||
				if (!matchedParameters.containsKey(callParameterName)) {
 | 
			
		||||
					logger.warn("Unable to locate the corresponding parameter value for '" + parameterName +
 | 
			
		||||
							"' within the parameter values provided: " + inParameters.keySet());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Matching " + inParameters.keySet() + " with " + callParameterNames.values());
 | 
			
		||||
			logger.debug("Found match for " + matchedParameters.keySet());
 | 
			
		||||
		}
 | 
			
		||||
		return matchedParameters;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Build the call string based on configuration and metadata information.
 | 
			
		||||
	 * @return the call string to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public String createCallString() {
 | 
			
		||||
		String callString;
 | 
			
		||||
		int parameterCount = 0;
 | 
			
		||||
		String catalogNameToUse = null;
 | 
			
		||||
		String schemaNameToUse = null;
 | 
			
		||||
 | 
			
		||||
		// For Oracle where catalogs are not supported we need to reverse the schema name
 | 
			
		||||
		// and the catalog name since the cataog is used for the package name
 | 
			
		||||
		if (this.metaDataProvider.isSupportsSchemasInProcedureCalls() &&
 | 
			
		||||
				!this.metaDataProvider.isSupportsCatalogsInProcedureCalls()) {
 | 
			
		||||
			schemaNameToUse = this.metaDataProvider.catalogNameToUse(this.getCatalogName());
 | 
			
		||||
			catalogNameToUse = this.metaDataProvider.schemaNameToUse(this.getSchemaName());
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			catalogNameToUse = this.metaDataProvider.catalogNameToUse(this.getCatalogName());
 | 
			
		||||
			schemaNameToUse = this.metaDataProvider.schemaNameToUse(this.getSchemaName());
 | 
			
		||||
		}
 | 
			
		||||
		String procedureNameToUse = this.metaDataProvider.procedureNameToUse(this.getProcedureName());
 | 
			
		||||
		if (this.isFunction() || this.isReturnValueRequired()) {
 | 
			
		||||
			callString = "{? = call " +
 | 
			
		||||
					(catalogNameToUse != null && catalogNameToUse.length() > 0 ? catalogNameToUse + "." : "") +
 | 
			
		||||
					(schemaNameToUse != null && schemaNameToUse.length() > 0 ? schemaNameToUse + "." : "") +
 | 
			
		||||
					procedureNameToUse + "(";
 | 
			
		||||
			parameterCount = -1;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			callString = "{call " +
 | 
			
		||||
					(catalogNameToUse != null && catalogNameToUse.length() > 0 ? catalogNameToUse + "." : "") +
 | 
			
		||||
					(schemaNameToUse != null && schemaNameToUse.length() > 0 ? schemaNameToUse + "." : "") +
 | 
			
		||||
					procedureNameToUse + "(";
 | 
			
		||||
		}
 | 
			
		||||
		for (SqlParameter parameter : this.callParameters) {
 | 
			
		||||
			if (!(parameter.isResultsParameter())) {
 | 
			
		||||
				if (parameterCount > 0) {
 | 
			
		||||
					callString += ", ";
 | 
			
		||||
				}
 | 
			
		||||
				if (parameterCount >= 0) {
 | 
			
		||||
					callString += "?";
 | 
			
		||||
				}
 | 
			
		||||
				parameterCount++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		callString += ")}";
 | 
			
		||||
 | 
			
		||||
		return callString;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,175 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface specifying the API to be implemented by a class providing call metadata.
 | 
			
		||||
 * This is intended for internal use by Spring's
 | 
			
		||||
 * {@link org.springframework.jdbc.core.simple.SimpleJdbcTemplate}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public interface CallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize using the provided DatabaseMetData.
 | 
			
		||||
	 * @param databaseMetaData used to retrieve database specific information
 | 
			
		||||
	 * @throws SQLException in case of initialization failure
 | 
			
		||||
	 */
 | 
			
		||||
	void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize the database specific management of procedure column meta data.
 | 
			
		||||
	 * This is only called for databases that are supported. This initalization
 | 
			
		||||
	 * can be turned off by specifying that column meta data should not be used.
 | 
			
		||||
	 * @param databaseMetaData used to retreive database specific information
 | 
			
		||||
	 * @param catalogName name of catalog to use or null
 | 
			
		||||
	 * @param schemaName name of schema name to use or null
 | 
			
		||||
	 * @param procedureName name of the stored procedure
 | 
			
		||||
	 * @throws SQLException in case of initialization failure
 | 
			
		||||
	 * @see	org.springframework.jdbc.core.simple.SimpleJdbcCall#withoutProcedureColumnMetaDataAccess()
 | 
			
		||||
	 */
 | 
			
		||||
	void initializeWithProcedureColumnMetaData(
 | 
			
		||||
			DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName)
 | 
			
		||||
			throws SQLException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the procedure name passed in to match the meta data currently used.
 | 
			
		||||
	 * This could include alterig the case.
 | 
			
		||||
	 */
 | 
			
		||||
	String procedureNameToUse(String procedureName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the catalog name passed in to match the meta data currently used.
 | 
			
		||||
	 * This could include alterig the case.
 | 
			
		||||
	 */
 | 
			
		||||
	String catalogNameToUse(String catalogName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the schema name passed in to match the meta data currently used.
 | 
			
		||||
	 * This could include alterig the case.
 | 
			
		||||
	 */
 | 
			
		||||
	String schemaNameToUse(String schemaName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the catalog name passed in to match the meta data currently used.
 | 
			
		||||
	 * The reyurned value will be used for meta data lookups.  This could include alterig the case used or
 | 
			
		||||
	 * providing a base catalog if mone provided.
 | 
			
		||||
	 */
 | 
			
		||||
	String metaDataCatalogNameToUse(String catalogName) ;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the schema name passed in to match the meta data currently used.
 | 
			
		||||
	 * The reyurned value will be used for meta data lookups.  This could include alterig the case used or
 | 
			
		||||
	 * providing a base schema if mone provided.
 | 
			
		||||
	 */
 | 
			
		||||
	String metaDataSchemaNameToUse(String schemaName) ;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the column name passed in to match the meta data currently used.
 | 
			
		||||
	 * This could include alterig the case.
 | 
			
		||||
	 * @param parameterName name of the parameter of column
 | 
			
		||||
	 */
 | 
			
		||||
	String parameterNameToUse(String parameterName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a default out parameter based on the provided meta data.  This is used when no expicit
 | 
			
		||||
	 * parameter declaration has been made.
 | 
			
		||||
	 * @param parameterName the name of the parameter
 | 
			
		||||
	 * @param meta meta data used for this call
 | 
			
		||||
	 * @return the configured SqlOutParameter
 | 
			
		||||
	 */
 | 
			
		||||
	SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a default inout parameter based on the provided meta data.  This is used when no expicit
 | 
			
		||||
	 * parameter declaration has been made.
 | 
			
		||||
	 * @param parameterName the name of the parameter
 | 
			
		||||
	 * @param meta meta data used for this call
 | 
			
		||||
	 * @return the configured SqlInOutParameter
 | 
			
		||||
	 */
 | 
			
		||||
	SqlParameter createDefaultInOutParameter(String parameterName, CallParameterMetaData meta);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a default in parameter based on the provided meta data.  This is used when no expicit
 | 
			
		||||
	 * parameter declaration has been made.
 | 
			
		||||
	 * @param parameterName the name of the parameter
 | 
			
		||||
	 * @param meta meta data used for this call
 | 
			
		||||
	 * @return the configured SqlParameter
 | 
			
		||||
	 */
 | 
			
		||||
	SqlParameter createDefaultInParameter(String parameterName, CallParameterMetaData meta);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the current user.  Useful for meta data lookups etc.
 | 
			
		||||
	 * @return current user name from database connection
 | 
			
		||||
	 */
 | 
			
		||||
	String getUserName();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support returning resultsets that should be retreived with the JDBC call
 | 
			
		||||
	 * {@link java.sql.Statement#getResultSet()}
 | 
			
		||||
	 */
 | 
			
		||||
	boolean isReturnResultSetSupported();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support returning resultsets as ref cursors to be retreived with
 | 
			
		||||
	 * {@link java.sql.CallableStatement#getObject(int)} for the specified column.
 | 
			
		||||
	 */
 | 
			
		||||
	boolean isRefCursorSupported();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the {@link java.sql.Types} type for columns that return resultsets as ref cursors if this feature
 | 
			
		||||
	 * is supported.
 | 
			
		||||
	 */
 | 
			
		||||
	int getRefCursorSqlType();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Are we using the meta data for the procedure columns?
 | 
			
		||||
	 */
 | 
			
		||||
	boolean isProcedureColumnMetaDataUsed();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Should we bypass the return parameter with the specified name.
 | 
			
		||||
	 * This allows the database specific implementation to skip the processing
 | 
			
		||||
	 * for specific results returned by the database call.
 | 
			
		||||
	 */
 | 
			
		||||
	boolean byPassReturnParameter(String parameterName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the call parameter metadata that is currently used.
 | 
			
		||||
	 * @return List of {@link CallParameterMetaData}
 | 
			
		||||
	 */
 | 
			
		||||
	List<CallParameterMetaData> getCallParameterMetaData();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does the database support the use of catalog name in procedure calls
 | 
			
		||||
	 */
 | 
			
		||||
	boolean isSupportsCatalogsInProcedureCalls();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does the database support the use of schema name in procedure calls
 | 
			
		||||
	 */
 | 
			
		||||
	boolean isSupportsSchemasInProcedureCalls();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,140 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessResourceFailureException;
 | 
			
		||||
import org.springframework.jdbc.support.DatabaseMetaDataCallback;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
import org.springframework.jdbc.support.MetaDataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Factory used to create a {@link CallMetaDataProvider} implementation based on the type of databse being used.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class CallMetaDataProviderFactory {
 | 
			
		||||
 | 
			
		||||
	/** Logger */
 | 
			
		||||
	private static final Log logger = LogFactory.getLog(CallMetaDataProviderFactory.class);
 | 
			
		||||
 | 
			
		||||
	/** List of supported database products for procedure calls */
 | 
			
		||||
	public static final List<String> supportedDatabaseProductsForProcedures = Arrays.asList(
 | 
			
		||||
			"Apache Derby",
 | 
			
		||||
			"DB2",
 | 
			
		||||
			"MySQL",
 | 
			
		||||
			"Microsoft SQL Server",
 | 
			
		||||
			"Oracle",
 | 
			
		||||
			"PostgreSQL",
 | 
			
		||||
			"Sybase"
 | 
			
		||||
		);
 | 
			
		||||
	/** List of supported database products for function calls */
 | 
			
		||||
	public static final List<String> supportedDatabaseProductsForFunctions = Arrays.asList(
 | 
			
		||||
			"MySQL",
 | 
			
		||||
			"Microsoft SQL Server",
 | 
			
		||||
			"Oracle",
 | 
			
		||||
			"PostgreSQL"
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a CallMetaDataProvider based on the database metedata
 | 
			
		||||
	 * @param dataSource used to retrieve metedata
 | 
			
		||||
	 * @param context the class that holds configuration and metedata
 | 
			
		||||
	 * @return instance of the CallMetaDataProvider implementation to be used 
 | 
			
		||||
	 */
 | 
			
		||||
	static public CallMetaDataProvider createMetaDataProvider(DataSource dataSource, final CallMetaDataContext context) {
 | 
			
		||||
		try {
 | 
			
		||||
			return (CallMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() {
 | 
			
		||||
				public Object processMetaData(DatabaseMetaData databaseMetaData) throws SQLException, MetaDataAccessException {
 | 
			
		||||
					String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
 | 
			
		||||
					boolean accessProcedureColumnMetaData = context.isAccessCallParameterMetaData();
 | 
			
		||||
					if (context.isFunction()) {
 | 
			
		||||
						if (!supportedDatabaseProductsForFunctions.contains(databaseProductName)) {
 | 
			
		||||
							if (logger.isWarnEnabled()) {
 | 
			
		||||
								logger.warn(databaseProductName + " is not one of the databases fully supported for function calls " +
 | 
			
		||||
										"-- supported are: " + supportedDatabaseProductsForFunctions);
 | 
			
		||||
							}
 | 
			
		||||
							if (accessProcedureColumnMetaData) {
 | 
			
		||||
								logger.warn("Metadata processing disabled - you must specify all parameters explicitly");
 | 
			
		||||
								accessProcedureColumnMetaData = false;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						if (!supportedDatabaseProductsForProcedures.contains(databaseProductName)) {
 | 
			
		||||
							if (logger.isWarnEnabled()) {
 | 
			
		||||
								logger.warn(databaseProductName + " is not one of the databases fully supported for procedure calls " +
 | 
			
		||||
										"-- supported are: " + supportedDatabaseProductsForProcedures);
 | 
			
		||||
							}
 | 
			
		||||
							if (accessProcedureColumnMetaData) {
 | 
			
		||||
								logger.warn("Metadata processing disabled - you must specify all parameters explicitly");
 | 
			
		||||
								accessProcedureColumnMetaData = false;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					CallMetaDataProvider provider;
 | 
			
		||||
					if ("Oracle".equals(databaseProductName)) {
 | 
			
		||||
						provider = new OracleCallMetaDataProvider(databaseMetaData);
 | 
			
		||||
					}
 | 
			
		||||
					else if ("DB2".equals(databaseProductName)) {
 | 
			
		||||
						provider = new Db2CallMetaDataProvider((databaseMetaData));
 | 
			
		||||
					}
 | 
			
		||||
					else if ("Apache Derby".equals(databaseProductName)) {
 | 
			
		||||
						provider = new DerbyCallMetaDataProvider((databaseMetaData));
 | 
			
		||||
					}
 | 
			
		||||
					else if ("PostgreSQL".equals(databaseProductName)) {
 | 
			
		||||
						provider = new PostgresCallMetaDataProvider((databaseMetaData));
 | 
			
		||||
					}
 | 
			
		||||
					else if ("Sybase".equals(databaseProductName)) {
 | 
			
		||||
						provider = new SybaseCallMetaDataProvider((databaseMetaData));
 | 
			
		||||
					}
 | 
			
		||||
					else if ("Microsoft SQL Server".equals(databaseProductName)) {
 | 
			
		||||
						provider = new SqlServerCallMetaDataProvider((databaseMetaData));
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						provider = new GenericCallMetaDataProvider(databaseMetaData);
 | 
			
		||||
					}
 | 
			
		||||
					if (logger.isDebugEnabled()) {
 | 
			
		||||
						logger.debug("Using " + provider.getClass().getName());
 | 
			
		||||
					}
 | 
			
		||||
					provider.initializeWithMetaData(databaseMetaData);
 | 
			
		||||
					if (accessProcedureColumnMetaData) {
 | 
			
		||||
						provider.initializeWithProcedureColumnMetaData(
 | 
			
		||||
								databaseMetaData, context.getCatalogName(), context.getSchemaName(), context.getProcedureName());
 | 
			
		||||
					}
 | 
			
		||||
					return provider;
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
		catch (MetaDataAccessException ex) {
 | 
			
		||||
			throw new DataAccessResourceFailureException("Error retreiving database metadata", ex);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Holder of metadata for a specific parameter that is used for call processing.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class CallParameterMetaData {
 | 
			
		||||
	private String parameterName;
 | 
			
		||||
	private int parameterType;
 | 
			
		||||
	private int sqlType;
 | 
			
		||||
	private String typeName;
 | 
			
		||||
	private boolean nullable;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor taking all the properties
 | 
			
		||||
	 */
 | 
			
		||||
	public CallParameterMetaData(String columnName, int columnType, int sqlType, String typeName, boolean nullable) {
 | 
			
		||||
		this.parameterName = columnName;
 | 
			
		||||
		this.parameterType = columnType;
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
		this.typeName = typeName;
 | 
			
		||||
		this.nullable = nullable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the parameter name.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getParameterName() {
 | 
			
		||||
		return parameterName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the parameter type.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getParameterType() {
 | 
			
		||||
		return parameterType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the parameter SQL type.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getSqlType() {
 | 
			
		||||
		return sqlType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the parameter type name.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getTypeName() {
 | 
			
		||||
		return typeName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get whether the parameter is nullable.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isNullable() {
 | 
			
		||||
		return nullable;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * DB2 specific implementation for the {@link CallMetaDataProvider} interface.
 | 
			
		||||
 * This class is intended for internal use by the Simple JDBC classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class Db2CallMetaDataProvider extends GenericCallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	public Db2CallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		try {
 | 
			
		||||
			setSupportsCatalogsInProcedureCalls(databaseMetaData.supportsCatalogsInProcedureCalls());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.debug("Error retrieving 'DatabaseMetaData.supportsCatalogsInProcedureCalls' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setSupportsSchemasInProcedureCalls(databaseMetaData.supportsSchemasInProcedureCalls());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.debug("Error retrieving 'DatabaseMetaData.supportsSchemasInProcedureCalls' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.debug("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.debug("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String metaDataSchemaNameToUse(String schemaName) {
 | 
			
		||||
		// Use current user schema if no schema specified
 | 
			
		||||
		return schemaName == null ? getUserName().toUpperCase() : super.metaDataSchemaNameToUse(schemaName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Derby specific implementation for the {@link CallMetaDataProvider} interface.
 | 
			
		||||
 * This class is intended for internal use by the Simple JDBC classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class DerbyCallMetaDataProvider extends GenericCallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	public DerbyCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String metaDataSchemaNameToUse(String schemaName) {
 | 
			
		||||
		// Use current user schema if no schema specified
 | 
			
		||||
		return schemaName == null ? getUserName().toUpperCase() : super.metaDataSchemaNameToUse(schemaName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,364 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.SqlOutParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlInOutParameter;
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic implementation for the {@link CallMetaDataProvider} interface.
 | 
			
		||||
 * This class can be extended to provide database specific behavior.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class GenericCallMetaDataProvider implements CallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	/** Logger available to subclasses */
 | 
			
		||||
	protected static final Log logger = LogFactory.getLog(CallMetaDataProvider.class);
 | 
			
		||||
 | 
			
		||||
	private boolean procedureColumnMetaDataUsed = false;
 | 
			
		||||
 | 
			
		||||
	private String userName;
 | 
			
		||||
 | 
			
		||||
	private boolean supportsCatalogsInProcedureCalls = true;
 | 
			
		||||
 | 
			
		||||
	private boolean supportsSchemasInProcedureCalls = true;
 | 
			
		||||
 | 
			
		||||
	private boolean storesUpperCaseIdentifiers = true;
 | 
			
		||||
 | 
			
		||||
	private boolean storesLowerCaseIdentifiers = false;
 | 
			
		||||
 | 
			
		||||
	private List<CallParameterMetaData> callParameterMetaData = new ArrayList<CallParameterMetaData>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor used to initialize with provided database meta data.
 | 
			
		||||
	 * @param databaseMetaData meta data to be used
 | 
			
		||||
	 */
 | 
			
		||||
	protected GenericCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		this.userName = databaseMetaData.getUserName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		try {
 | 
			
		||||
			setSupportsCatalogsInProcedureCalls(databaseMetaData.supportsCatalogsInProcedureCalls());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.supportsCatalogsInProcedureCalls' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setSupportsSchemasInProcedureCalls(databaseMetaData.supportsSchemasInProcedureCalls());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.supportsSchemasInProcedureCalls' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void initializeWithProcedureColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName)
 | 
			
		||||
			throws SQLException {
 | 
			
		||||
 | 
			
		||||
		this.procedureColumnMetaDataUsed = true;
 | 
			
		||||
		processProcedureColumns(databaseMetaData, catalogName, schemaName,  procedureName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List<CallParameterMetaData> getCallParameterMetaData() {
 | 
			
		||||
		return callParameterMetaData;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String procedureNameToUse(String procedureName) {
 | 
			
		||||
		if (procedureName == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		else if (isStoresUpperCaseIdentifiers())
 | 
			
		||||
			return procedureName.toUpperCase();
 | 
			
		||||
		else if(isStoresLowerCaseIdentifiers())
 | 
			
		||||
			return procedureName.toLowerCase();
 | 
			
		||||
		else
 | 
			
		||||
			return procedureName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String catalogNameToUse(String catalogName) {
 | 
			
		||||
		if (catalogName == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		else if (isStoresUpperCaseIdentifiers())
 | 
			
		||||
			return catalogName.toUpperCase();
 | 
			
		||||
		else if(isStoresLowerCaseIdentifiers())
 | 
			
		||||
			return catalogName.toLowerCase();
 | 
			
		||||
		else
 | 
			
		||||
		return catalogName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String schemaNameToUse(String schemaName) {
 | 
			
		||||
		if (schemaName == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		else if (isStoresUpperCaseIdentifiers())
 | 
			
		||||
			return schemaName.toUpperCase();
 | 
			
		||||
		else if(isStoresLowerCaseIdentifiers())
 | 
			
		||||
			return schemaName.toLowerCase();
 | 
			
		||||
		else
 | 
			
		||||
		return schemaName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String metaDataCatalogNameToUse(String catalogName) {
 | 
			
		||||
		if (isSupportsCatalogsInProcedureCalls()) {
 | 
			
		||||
			return catalogNameToUse(catalogName);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String metaDataSchemaNameToUse(String schemaName) {
 | 
			
		||||
		if (isSupportsSchemasInProcedureCalls()) {
 | 
			
		||||
			return schemaNameToUse(schemaName);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String parameterNameToUse(String parameterName) {
 | 
			
		||||
		if (parameterName == null) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		else if (isStoresUpperCaseIdentifiers()) {
 | 
			
		||||
			return parameterName.toUpperCase();
 | 
			
		||||
		}
 | 
			
		||||
		else if(isStoresLowerCaseIdentifiers()) {
 | 
			
		||||
			return parameterName.toLowerCase();
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return parameterName;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean byPassReturnParameter(String parameterName) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta) {
 | 
			
		||||
		return new SqlOutParameter(parameterName, meta.getSqlType());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SqlParameter createDefaultInOutParameter(String parameterName, CallParameterMetaData meta) {
 | 
			
		||||
		return new SqlInOutParameter(parameterName, meta.getSqlType());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SqlParameter createDefaultInParameter(String parameterName, CallParameterMetaData meta) {
 | 
			
		||||
		return new SqlParameter(parameterName, meta.getSqlType());		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getUserName() {
 | 
			
		||||
		return this.userName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isReturnResultSetSupported() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isRefCursorSupported() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int getRefCursorSqlType() {
 | 
			
		||||
		return Types.OTHER;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isProcedureColumnMetaDataUsed() {
 | 
			
		||||
		return this.procedureColumnMetaDataUsed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether the database supports the use of catalog name in procedure calls
 | 
			
		||||
	 */
 | 
			
		||||
	protected void setSupportsCatalogsInProcedureCalls(boolean supportsCatalogsInProcedureCalls) {
 | 
			
		||||
		this.supportsCatalogsInProcedureCalls = supportsCatalogsInProcedureCalls;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does the database support the use of catalog name in procedure calls
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isSupportsCatalogsInProcedureCalls() {
 | 
			
		||||
		return this.supportsCatalogsInProcedureCalls;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether the database supports the use of schema name in procedure calls
 | 
			
		||||
	 */
 | 
			
		||||
	protected void setSupportsSchemasInProcedureCalls(boolean supportsSchemasInProcedureCalls) {
 | 
			
		||||
		this.supportsSchemasInProcedureCalls = supportsSchemasInProcedureCalls;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does the database support the use of schema name in procedure calls
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isSupportsSchemasInProcedureCalls() {
 | 
			
		||||
		return this.supportsSchemasInProcedureCalls;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether the database uses upper case for identifiers
 | 
			
		||||
	 */
 | 
			
		||||
	protected void setStoresUpperCaseIdentifiers(boolean storesUpperCaseIdentifiers) {
 | 
			
		||||
		this.storesUpperCaseIdentifiers = storesUpperCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does the database use upper case for identifiers
 | 
			
		||||
	 */
 | 
			
		||||
	protected boolean isStoresUpperCaseIdentifiers() {
 | 
			
		||||
		return this.storesUpperCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether the database uses lower case for identifiers
 | 
			
		||||
	 */
 | 
			
		||||
	protected void setStoresLowerCaseIdentifiers(boolean storesLowerCaseIdentifiers) {
 | 
			
		||||
		this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does the database use lower case for identifiers
 | 
			
		||||
	 */
 | 
			
		||||
	protected boolean isStoresLowerCaseIdentifiers() {
 | 
			
		||||
		return this.storesLowerCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Process the procedure column metadata
 | 
			
		||||
	 */
 | 
			
		||||
	private void processProcedureColumns(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName) {
 | 
			
		||||
		ResultSet procs = null;
 | 
			
		||||
		String metaDataCatalogName = metaDataCatalogNameToUse(catalogName);
 | 
			
		||||
		String metaDataSchemaName = metaDataSchemaNameToUse(schemaName);
 | 
			
		||||
		String metaDataProcedureName = procedureNameToUse(procedureName);
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Retrieving metadata for " + metaDataCatalogName + "/" +
 | 
			
		||||
					metaDataSchemaName + "/" + metaDataProcedureName);
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			procs = databaseMetaData.getProcedures(
 | 
			
		||||
					metaDataCatalogName,
 | 
			
		||||
					metaDataSchemaName,
 | 
			
		||||
					metaDataProcedureName);
 | 
			
		||||
			List found = new ArrayList();
 | 
			
		||||
			while (procs.next()) {
 | 
			
		||||
				found.add(procs.getString("PROCEDURE_CAT") +
 | 
			
		||||
		          		"."+procs.getString("PROCEDURE_SCHEM") +
 | 
			
		||||
	    	      		"."+procs.getString("PROCEDURE_NAME"));
 | 
			
		||||
			}
 | 
			
		||||
			procs.close();
 | 
			
		||||
			if (found.size() > 1) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException("Unable to determine the correct call signature - " +
 | 
			
		||||
						"multiple procedures/functions/signatures for " + metaDataProcedureName + " found " + found);
 | 
			
		||||
			}
 | 
			
		||||
			if (found.size() < 1) {
 | 
			
		||||
				if (metaDataProcedureName.contains(".") && !StringUtils.hasText(metaDataCatalogName)) {
 | 
			
		||||
					String packageName = metaDataProcedureName.substring(0, metaDataProcedureName.indexOf("."));
 | 
			
		||||
					throw new InvalidDataAccessApiUsageException("Unable to determine the correct call signature for " +
 | 
			
		||||
							metaDataProcedureName + " - package name should be specified separately using " +
 | 
			
		||||
							"'.withCatalogName(\"" + packageName + "\")'");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			procs = databaseMetaData.getProcedureColumns(
 | 
			
		||||
					metaDataCatalogName,
 | 
			
		||||
					metaDataSchemaName,
 | 
			
		||||
					metaDataProcedureName,
 | 
			
		||||
					null);
 | 
			
		||||
			while (procs.next()) {
 | 
			
		||||
				String columnName = procs.getString("COLUMN_NAME");
 | 
			
		||||
				int columnType = procs.getInt("COLUMN_TYPE");
 | 
			
		||||
				if (columnName == null && (
 | 
			
		||||
						columnType == DatabaseMetaData.procedureColumnIn  ||
 | 
			
		||||
						columnType == DatabaseMetaData.procedureColumnInOut ||
 | 
			
		||||
						columnType == DatabaseMetaData.procedureColumnOut)) {
 | 
			
		||||
					if (logger.isDebugEnabled()) {
 | 
			
		||||
						logger.debug("Skipping metadata for: "
 | 
			
		||||
							+ columnName +
 | 
			
		||||
							" " + columnType +
 | 
			
		||||
							" " + procs.getInt("DATA_TYPE") +
 | 
			
		||||
							" " + procs.getString("TYPE_NAME") +
 | 
			
		||||
							" " + procs.getBoolean("NULLABLE") +
 | 
			
		||||
							" (probably a member of a collection)"
 | 
			
		||||
						);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					CallParameterMetaData meta = new CallParameterMetaData(
 | 
			
		||||
							columnName,
 | 
			
		||||
							columnType,
 | 
			
		||||
							procs.getInt("DATA_TYPE"),
 | 
			
		||||
							procs.getString("TYPE_NAME"),
 | 
			
		||||
							procs.getBoolean("NULLABLE")
 | 
			
		||||
					);
 | 
			
		||||
					callParameterMetaData.add(meta);
 | 
			
		||||
					if (logger.isDebugEnabled()) {
 | 
			
		||||
						logger.debug("Retrieved metadata: "
 | 
			
		||||
							+ meta.getParameterName() +
 | 
			
		||||
							" " + meta.getParameterType() +
 | 
			
		||||
							" " + meta.getSqlType() +
 | 
			
		||||
							" " + meta.getTypeName() +
 | 
			
		||||
							" " + meta.isNullable()
 | 
			
		||||
						);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error while retreiving metadata for procedure columns: " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		finally {
 | 
			
		||||
			try {
 | 
			
		||||
				if (procs != null)
 | 
			
		||||
					procs.close();
 | 
			
		||||
			}
 | 
			
		||||
			catch (SQLException se) {
 | 
			
		||||
				logger.warn("Problem closing resultset for procedure column metadata " + se.getMessage());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,421 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessResourceFailureException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A generic implementation of the {@link TableMetaDataProvider} that should provide enough features for all supported
 | 
			
		||||
 * databases.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class GenericTableMetaDataProvider implements TableMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	/** Logger available to subclasses */
 | 
			
		||||
	protected static final Log logger = LogFactory.getLog(TableMetaDataProvider.class);
 | 
			
		||||
 | 
			
		||||
	/** indicator whether column metadata should be used */
 | 
			
		||||
	private boolean tableColumnMetaDataUsed = false;
 | 
			
		||||
 | 
			
		||||
	/** the version of the database */
 | 
			
		||||
	private String databaseVersion;
 | 
			
		||||
 | 
			
		||||
	/** the name of the user currently connected */
 | 
			
		||||
	private String userName;
 | 
			
		||||
 | 
			
		||||
	/** indicates whether the identifiers are uppercased */
 | 
			
		||||
	private boolean storesUpperCaseIdentifiers = true;
 | 
			
		||||
 | 
			
		||||
	/** indicates whether the identifiers are lowercased */
 | 
			
		||||
	private boolean storesLowerCaseIdentifiers = false;
 | 
			
		||||
 | 
			
		||||
	/** indicates whether generated keys retrieval is supported */
 | 
			
		||||
	private boolean getGeneratedKeysSupported = true;
 | 
			
		||||
 | 
			
		||||
	/** indicates whether the use of a String[] for generated keys is supported */
 | 
			
		||||
	private boolean generatedKeysColumnNameArraySupported = true;
 | 
			
		||||
 | 
			
		||||
	/** database product we know that don't support the use of a String[] for generated keys */
 | 
			
		||||
	private List productsNotSupportingGeneratedKeysColumnNameArray = Arrays.asList(new String[] {"Apache Derby"});
 | 
			
		||||
 | 
			
		||||
	/** Collection of TableParameterMetaData objects */
 | 
			
		||||
	private List<TableParameterMetaData> insertParameterMetaData = new ArrayList<TableParameterMetaData>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor used to initialize with provided database meta data.
 | 
			
		||||
	 * @param databaseMetaData meta data to be used
 | 
			
		||||
	 * @throws SQLException
 | 
			
		||||
	 */
 | 
			
		||||
	protected GenericTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		userName = databaseMetaData.getUserName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get whether identifiers use upper case
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isStoresUpperCaseIdentifiers() {
 | 
			
		||||
		return storesUpperCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether identifiers use upper case
 | 
			
		||||
	 */
 | 
			
		||||
	public void setStoresUpperCaseIdentifiers(boolean storesUpperCaseIdentifiers) {
 | 
			
		||||
		this.storesUpperCaseIdentifiers = storesUpperCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get whether identifiers use lower case
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isStoresLowerCaseIdentifiers() {
 | 
			
		||||
		return storesLowerCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether identifiers use lower case
 | 
			
		||||
	 */
 | 
			
		||||
	public void setStoresLowerCaseIdentifiers(boolean storesLowerCaseIdentifiers) {
 | 
			
		||||
		this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isTableColumnMetaDataUsed() {
 | 
			
		||||
		return tableColumnMetaDataUsed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List<TableParameterMetaData> getTableParameterMetaData() {
 | 
			
		||||
		return insertParameterMetaData;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isGetGeneratedKeysSupported() {
 | 
			
		||||
		return getGeneratedKeysSupported;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isGetGeneratedKeysSimulated(){
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName) {
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether a column name array is supported for generated keys
 | 
			
		||||
	 */
 | 
			
		||||
	public void setGetGeneratedKeysSupported(boolean getGeneratedKeysSupported) {
 | 
			
		||||
		this.getGeneratedKeysSupported = getGeneratedKeysSupported;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public boolean isGeneratedKeysColumnNameArraySupported() {
 | 
			
		||||
		return generatedKeysColumnNameArraySupported;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether a column name array is supported for generated keys
 | 
			
		||||
	 */
 | 
			
		||||
	public void setGeneratedKeysColumnNameArraySupported(boolean generatedKeysColumnNameArraySupported) {
 | 
			
		||||
		this.generatedKeysColumnNameArraySupported = generatedKeysColumnNameArraySupported;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
 | 
			
		||||
		try {
 | 
			
		||||
			if (databaseMetaData.supportsGetGeneratedKeys()) {
 | 
			
		||||
				logger.debug("GetGeneratedKeys is supported");
 | 
			
		||||
				setGetGeneratedKeysSupported(true);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				logger.debug("GetGeneratedKeys is not supported");
 | 
			
		||||
				setGetGeneratedKeysSupported(false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.getGeneratedKeys' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			String databaseProductName = databaseMetaData.getDatabaseProductName();
 | 
			
		||||
			if (productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) {
 | 
			
		||||
				logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName);
 | 
			
		||||
				setGeneratedKeysColumnNameArraySupported(false);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				logger.debug("GeneratedKeysColumnNameArray is supported for " + databaseProductName);
 | 
			
		||||
				setGeneratedKeysColumnNameArraySupported(true);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			databaseVersion = databaseMetaData.getDatabaseProductVersion();
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers());
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName)
 | 
			
		||||
			throws SQLException {
 | 
			
		||||
 | 
			
		||||
		tableColumnMetaDataUsed = true;
 | 
			
		||||
 | 
			
		||||
		locateTableAndProcessMetaData(databaseMetaData, catalogName, schemaName, tableName);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String tableNameToUse(String tableName) {
 | 
			
		||||
		if (tableName == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		else if (isStoresUpperCaseIdentifiers())
 | 
			
		||||
			return tableName.toUpperCase();
 | 
			
		||||
		else if(isStoresLowerCaseIdentifiers())
 | 
			
		||||
			return tableName.toLowerCase();
 | 
			
		||||
		else
 | 
			
		||||
			return tableName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String catalogNameToUse(String catalogName) {
 | 
			
		||||
		if (catalogName == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		else if (isStoresUpperCaseIdentifiers())
 | 
			
		||||
			return catalogName.toUpperCase();
 | 
			
		||||
		else if(isStoresLowerCaseIdentifiers())
 | 
			
		||||
			return catalogName.toLowerCase();
 | 
			
		||||
		else
 | 
			
		||||
		return catalogName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String schemaNameToUse(String schemaName) {
 | 
			
		||||
		if (schemaName == null)
 | 
			
		||||
			return null;
 | 
			
		||||
		else if (isStoresUpperCaseIdentifiers())
 | 
			
		||||
			return schemaName.toUpperCase();
 | 
			
		||||
		else if(isStoresLowerCaseIdentifiers())
 | 
			
		||||
			return schemaName.toLowerCase();
 | 
			
		||||
		else
 | 
			
		||||
		return schemaName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String metaDataCatalogNameToUse(String catalogName) {
 | 
			
		||||
		return catalogNameToUse(catalogName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String metaDataSchemaNameToUse(String schemaName) {
 | 
			
		||||
		if (schemaName == null) {
 | 
			
		||||
			return schemaNameToUse(userName);
 | 
			
		||||
		}
 | 
			
		||||
		return schemaNameToUse(schemaName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide access to version info for subclasses 
 | 
			
		||||
	 */
 | 
			
		||||
	protected String getDatabaseVersion() {
 | 
			
		||||
		return databaseVersion;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method supporting the metedata processing for a table
 | 
			
		||||
	 */
 | 
			
		||||
	private void locateTableAndProcessMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) {
 | 
			
		||||
		Map<String, TableMetaData> tableMeta = new HashMap<String, TableMetaData>();
 | 
			
		||||
		ResultSet tables = null;
 | 
			
		||||
 | 
			
		||||
		try {
 | 
			
		||||
			tables = databaseMetaData.getTables(
 | 
			
		||||
				catalogNameToUse(catalogName),
 | 
			
		||||
				schemaNameToUse(schemaName),
 | 
			
		||||
				tableNameToUse(tableName),
 | 
			
		||||
				null);
 | 
			
		||||
			while (tables != null && tables.next()) {
 | 
			
		||||
				TableMetaData tmd = new TableMetaData();
 | 
			
		||||
				tmd.setCatalogName(tables.getString("TABLE_CAT"));
 | 
			
		||||
				tmd.setSchemaName(tables.getString("TABLE_SCHEM"));
 | 
			
		||||
				tmd.setTableName(tables.getString("TABLE_NAME"));
 | 
			
		||||
				tmd.setType(tables.getString("TABLE_TYPE"));
 | 
			
		||||
				if (tmd.getSchemaName() == null) {
 | 
			
		||||
					tableMeta.put(userName.toUpperCase(), tmd);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					tableMeta.put(tmd.getSchemaName().toUpperCase(), tmd);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error while accessing table meta data results" + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		finally {
 | 
			
		||||
			if (tables != null) {
 | 
			
		||||
				try {
 | 
			
		||||
					tables.close();
 | 
			
		||||
				} catch (SQLException e) {
 | 
			
		||||
					logger.warn("Error while closing table meta data reults" + e.getMessage());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (tableMeta.size() < 1) {
 | 
			
		||||
			logger.warn("Unable to locate table meta data for '" + tableName +"' -- column names must be provided");
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			TableMetaData tmd = null;
 | 
			
		||||
			if (schemaName == null) {
 | 
			
		||||
				tmd = tableMeta.get(userName.toUpperCase());
 | 
			
		||||
				if (tmd == null) {
 | 
			
		||||
					tmd = tableMeta.get("PUBLIC");
 | 
			
		||||
					if (tmd == null) {
 | 
			
		||||
						tmd = tableMeta.get("DBO");
 | 
			
		||||
					}
 | 
			
		||||
					if (tmd == null) {
 | 
			
		||||
						throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + tableName + "' in the default schema");
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				tmd = tableMeta.get(schemaName.toUpperCase());
 | 
			
		||||
				if (tmd == null) {
 | 
			
		||||
					throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + tableName + "' in the '" + schemaName + "' schema");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			processTableColumns(databaseMetaData, tmd);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method supporting the metedata processing for a table's columns
 | 
			
		||||
	 */
 | 
			
		||||
	private void processTableColumns(DatabaseMetaData databaseMetaData, TableMetaData tmd) {
 | 
			
		||||
		ResultSet tableColumns = null;
 | 
			
		||||
		String metaDataCatalogName = metaDataCatalogNameToUse(tmd.getCatalogName());
 | 
			
		||||
		String metaDataSchemaName = metaDataSchemaNameToUse(tmd.getSchemaName());
 | 
			
		||||
		String metaDataTableName = tableNameToUse(tmd.getTableName());
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Retrieving metadata for " + metaDataCatalogName + "/" +
 | 
			
		||||
					metaDataSchemaName + "/" + metaDataTableName);
 | 
			
		||||
		}
 | 
			
		||||
		try {
 | 
			
		||||
			tableColumns = databaseMetaData.getColumns(
 | 
			
		||||
					metaDataCatalogName,
 | 
			
		||||
					metaDataSchemaName,
 | 
			
		||||
					metaDataTableName,
 | 
			
		||||
					null);
 | 
			
		||||
			while (tableColumns.next()) {
 | 
			
		||||
				TableParameterMetaData meta = new TableParameterMetaData(
 | 
			
		||||
						tableColumns.getString("COLUMN_NAME"),
 | 
			
		||||
						tableColumns.getInt("DATA_TYPE"),
 | 
			
		||||
						tableColumns.getBoolean("NULLABLE")
 | 
			
		||||
				);
 | 
			
		||||
				insertParameterMetaData.add(meta);
 | 
			
		||||
				if (logger.isDebugEnabled()) {
 | 
			
		||||
					logger.debug("Retrieved metadata: "
 | 
			
		||||
						+ meta.getParameterName() +
 | 
			
		||||
						" " + meta.getSqlType() +
 | 
			
		||||
						" " + meta.isNullable()
 | 
			
		||||
					);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (SQLException se) {
 | 
			
		||||
			logger.warn("Error while retreiving metadata for procedure columns: " + se.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
		finally {
 | 
			
		||||
			try {
 | 
			
		||||
				if (tableColumns != null)
 | 
			
		||||
					tableColumns.close();
 | 
			
		||||
			}
 | 
			
		||||
			catch (SQLException se) {
 | 
			
		||||
				logger.warn("Problem closing resultset for procedure column metadata " + se.getMessage());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Class representing table meta data
 | 
			
		||||
	 */
 | 
			
		||||
	private class TableMetaData {
 | 
			
		||||
		private String catalogName;
 | 
			
		||||
		private String schemaName;
 | 
			
		||||
		private String tableName;
 | 
			
		||||
		private String type;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		public String getCatalogName() {
 | 
			
		||||
			return catalogName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void setCatalogName(String catalogName) {
 | 
			
		||||
			this.catalogName = catalogName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String getSchemaName() {
 | 
			
		||||
			return schemaName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void setSchemaName(String schemaName) {
 | 
			
		||||
			this.schemaName = schemaName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String getTableName() {
 | 
			
		||||
			return tableName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void setTableName(String tableName) {
 | 
			
		||||
			this.tableName = tableName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public String getType() {
 | 
			
		||||
			return type;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void setType(String type) {
 | 
			
		||||
			this.type = type;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The HSQL specific implementation of the {@link TableMetaDataProvider}. Suports a feature for 
 | 
			
		||||
 * retreiving generated keys without the JDBC 3.0 getGeneratedKeys support.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class HsqlTableMetaDataProvider extends GenericTableMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	public HsqlTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public boolean isGetGeneratedKeysSimulated() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName) {
 | 
			
		||||
		return "select max(identity()) from " + tableName;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.ColumnMapRowMapper;
 | 
			
		||||
import org.springframework.jdbc.core.SqlOutParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlInOutParameter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Oracle specific implementation for the {@link CallMetaDataProvider} interface.
 | 
			
		||||
 * This class is intended for internal use by the Simple JDBC classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class OracleCallMetaDataProvider extends GenericCallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	private static final String REF_CURSOR_NAME = "REF CURSOR";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public OracleCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean isReturnResultSetSupported() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean isRefCursorSupported() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public int getRefCursorSqlType() {
 | 
			
		||||
		return -10;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String metaDataCatalogNameToUse(String catalogName) {
 | 
			
		||||
		// Oracle uses catalog name for package name or an empty string if no package
 | 
			
		||||
		return catalogName == null ? "" : catalogNameToUse(catalogName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String metaDataSchemaNameToUse(String schemaName) {
 | 
			
		||||
		// Use current user schema if no schema specified
 | 
			
		||||
		return schemaName == null ? getUserName() : super.metaDataSchemaNameToUse(schemaName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta) {
 | 
			
		||||
		if (meta.getSqlType() == Types.OTHER && REF_CURSOR_NAME.equals(meta.getTypeName())) {
 | 
			
		||||
			return new SqlOutParameter(parameterName, getRefCursorSqlType(), new ColumnMapRowMapper());
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return super.createDefaultOutParameter(parameterName, meta);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlOutParameter;
 | 
			
		||||
import org.springframework.jdbc.core.ColumnMapRowMapper;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Oracle specific implementation for the {@link org.springframework.jdbc.core.metadata.CallMetaDataProvider} interface.
 | 
			
		||||
 * This class is intended for internal use by the Simple JDBC classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class PostgresCallMetaDataProvider extends GenericCallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	private static final String RETURN_VALUE_NAME = "returnValue";
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	public PostgresCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean isReturnResultSetSupported() {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean isRefCursorSupported() {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public int getRefCursorSqlType() {
 | 
			
		||||
		return Types.OTHER;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String metaDataSchemaNameToUse(String schemaName) {
 | 
			
		||||
		// Use public schema if no schema specified
 | 
			
		||||
		return schemaName == null ? "public" : super.metaDataSchemaNameToUse(schemaName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta) {
 | 
			
		||||
		if (meta.getSqlType() == Types.OTHER && "refcursor".equals(meta.getTypeName())) {
 | 
			
		||||
			return new SqlOutParameter(parameterName, getRefCursorSqlType(), new ColumnMapRowMapper());
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return super.createDefaultOutParameter(parameterName, meta);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean byPassReturnParameter(String parameterName) {
 | 
			
		||||
		return (RETURN_VALUE_NAME.equals(parameterName) ||
 | 
			
		||||
				super.byPassReturnParameter(parameterName));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The HSQL specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. Suports a feature for
 | 
			
		||||
 * retreiving generated keys without the JDBC 3.0 getGeneratedKeys support.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class PostgresTableMetaDataProvider extends GenericTableMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	public PostgresTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public boolean isGetGeneratedKeysSimulated() {
 | 
			
		||||
		if (getDatabaseVersion().compareTo("8.2.0") >= 0) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			logger.warn("PostgreSQL does not support getGeneratedKeys or INSERT ... RETURNING in version " + getDatabaseVersion());
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName) {
 | 
			
		||||
		return "RETURNING " + keyColumnName;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SQL Server specific implementation for the {@link CallMetaDataProvider} interface.
 | 
			
		||||
 * This class is intended for internal use by the Simple JDBC classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class SqlServerCallMetaDataProvider extends GenericCallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	private static final String REMOVABLE_COLUMN_PREFIX = "@";
 | 
			
		||||
 | 
			
		||||
	private static final String RETURN_VALUE_NAME = "@RETURN_VALUE";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public SqlServerCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String parameterNameToUse(String parameterName) {
 | 
			
		||||
		if (parameterName == null) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		else if (parameterName.length() > 1 && parameterName.startsWith(REMOVABLE_COLUMN_PREFIX)) {
 | 
			
		||||
			return super.parameterNameToUse(parameterName.substring(1));
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return super.parameterNameToUse(parameterName);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean byPassReturnParameter(String parameterName) {
 | 
			
		||||
		return (RETURN_VALUE_NAME.equals(parameterName) || super.byPassReturnParameter(parameterName));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sybase specific implementation for the {@link CallMetaDataProvider} interface.
 | 
			
		||||
 * This class is intended for internal use by the Simple JDBC classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class SybaseCallMetaDataProvider extends GenericCallMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	private static final String REMOVABLE_COLUMN_PREFIX = "@";
 | 
			
		||||
 | 
			
		||||
	private static final String RETURN_VALUE_NAME = "RETURN_VALUE";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public SybaseCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
 | 
			
		||||
		super(databaseMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public String parameterNameToUse(String parameterName) {
 | 
			
		||||
		if (parameterName == null) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		else if (parameterName.length() > 1 && parameterName.startsWith(REMOVABLE_COLUMN_PREFIX)) {
 | 
			
		||||
			return super.parameterNameToUse(parameterName.substring(1));
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return super.parameterNameToUse(parameterName);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean byPassReturnParameter(String parameterName) {
 | 
			
		||||
		return (RETURN_VALUE_NAME.equals(parameterName) ||
 | 
			
		||||
				RETURN_VALUE_NAME.equals(parameterNameToUse(parameterName)) ||
 | 
			
		||||
				super.byPassReturnParameter(parameterName));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,347 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.jdbc.core.SqlTypeValue;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to manage context metadata used for the configuration
 | 
			
		||||
 * and execution of operations on a database table.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class TableMetaDataContext {
 | 
			
		||||
 | 
			
		||||
	/** Logger available to subclasses */
 | 
			
		||||
	protected final Log logger = LogFactory.getLog(getClass());
 | 
			
		||||
 | 
			
		||||
	/** name of procedure to call **/
 | 
			
		||||
	private String tableName;
 | 
			
		||||
 | 
			
		||||
	/** name of catalog for call **/
 | 
			
		||||
	private String catalogName;
 | 
			
		||||
 | 
			
		||||
	/** name of schema for call **/
 | 
			
		||||
	private String schemaName;
 | 
			
		||||
 | 
			
		||||
	/** List of columns objects to be used in this context */
 | 
			
		||||
	private List<String> tableColumns = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
	/** should we access insert parameter meta data info or not */
 | 
			
		||||
	private boolean accessTableParameterMetaData = true;
 | 
			
		||||
 | 
			
		||||
	/** the provider of call meta data */
 | 
			
		||||
	private TableMetaDataProvider metaDataProvider;
 | 
			
		||||
 | 
			
		||||
	/** are we using generated key columns */
 | 
			
		||||
	private boolean generatedKeyColumnsUsed = false;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the name of the table for this context.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setTableName(String tableName) {
 | 
			
		||||
		this.tableName = tableName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the table for this context.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getTableName() {
 | 
			
		||||
		return this.tableName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the name of the catalog for this context.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setCatalogName(String catalogName) {
 | 
			
		||||
		this.catalogName = catalogName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the catalog for this context.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getCatalogName() {
 | 
			
		||||
		return this.catalogName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the name of the schema for this context.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSchemaName(String schemaName) {
 | 
			
		||||
		this.schemaName = schemaName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the schema for this context.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSchemaName() {
 | 
			
		||||
		return this.schemaName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether we should access table column meta data.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setAccessTableParameterMetaData(boolean accessTableParameterMetaData) {
 | 
			
		||||
		this.accessTableParameterMetaData = accessTableParameterMetaData;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Are we accessing table meta data?
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isAccessTableParameterMetaData() {
 | 
			
		||||
		return this.accessTableParameterMetaData;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get a List of the table column names.
 | 
			
		||||
	 */
 | 
			
		||||
	public List<String> getTableColumns() {
 | 
			
		||||
		return this.tableColumns;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support the JDBC 3.0 feature of retreiving generated keys
 | 
			
		||||
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isGetGeneratedKeysSupported() {
 | 
			
		||||
		return this.metaDataProvider.isGetGeneratedKeysSupported();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support simple query to retrieve generated keys
 | 
			
		||||
	 * when the JDBC 3.0 feature is not supported
 | 
			
		||||
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isGetGeneratedKeysSimulated() {
 | 
			
		||||
		return this.metaDataProvider.isGetGeneratedKeysSimulated();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support simple query to retrieve generated keys
 | 
			
		||||
	 * when the JDBC 3.0 feature is not supported
 | 
			
		||||
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) {
 | 
			
		||||
		return this.metaDataProvider.getSimpleQueryForGetGeneratedKey(tableName, keyColumnName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Is a column name String array for retreiving generated keys supported
 | 
			
		||||
	 * {@link java.sql.Connection#createStruct(String, Object[])}?
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isGeneratedKeysColumnNameArraySupported() {
 | 
			
		||||
		return this.metaDataProvider.isGeneratedKeysColumnNameArraySupported();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Process the current meta data with the provided configuration options
 | 
			
		||||
	 * @param dataSource the DataSource being used
 | 
			
		||||
	 * @param declaredColumns any coluns that are declared
 | 
			
		||||
	 * @param generatedKeyNames name of generated keys
 | 
			
		||||
	 */
 | 
			
		||||
	public void processMetaData(DataSource dataSource, List<String> declaredColumns, String[] generatedKeyNames) {
 | 
			
		||||
		this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
 | 
			
		||||
		this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Compare columns created from metadata with declared columns and return a reconciled list.
 | 
			
		||||
	 * @param declaredColumns declared column names
 | 
			
		||||
	 * @param generatedKeyNames names of generated key columns
 | 
			
		||||
	 */
 | 
			
		||||
	private List<String> reconcileColumnsToUse(List<String> declaredColumns, String[] generatedKeyNames) {
 | 
			
		||||
		if (generatedKeyNames.length > 0) {
 | 
			
		||||
			generatedKeyColumnsUsed = true;
 | 
			
		||||
		}
 | 
			
		||||
		if (declaredColumns.size() > 0) {
 | 
			
		||||
			return new ArrayList<String>(declaredColumns);
 | 
			
		||||
		}
 | 
			
		||||
		Set keys = new HashSet(generatedKeyNames.length);
 | 
			
		||||
		for (String key : generatedKeyNames) {
 | 
			
		||||
			keys.add(key.toUpperCase());
 | 
			
		||||
		}
 | 
			
		||||
		List<String> columns = new ArrayList<String>();
 | 
			
		||||
		for (TableParameterMetaData meta : metaDataProvider.getTableParameterMetaData()) {
 | 
			
		||||
			if (!keys.contains(meta.getParameterName().toUpperCase())) {
 | 
			
		||||
				columns.add(meta.getParameterName());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return columns;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match the provided column names and values with the list of columns used.
 | 
			
		||||
	 * @param parameterSource the parameter names and values
 | 
			
		||||
	 */
 | 
			
		||||
	public List<Object> matchInParameterValuesWithInsertColumns(SqlParameterSource parameterSource) {
 | 
			
		||||
		List<Object> values = new ArrayList<Object>();
 | 
			
		||||
		// for parameter source lookups we need to provide caseinsensitive lookup support since the
 | 
			
		||||
		// database metadata is not necessarily providing case sensitive column names
 | 
			
		||||
		Map caseInsensitiveParameterNames =
 | 
			
		||||
				SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource);
 | 
			
		||||
		for (String column : tableColumns) {
 | 
			
		||||
			if (parameterSource.hasValue(column)) {
 | 
			
		||||
				values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, column));
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				String lowerCaseName = column.toLowerCase();
 | 
			
		||||
				if (parameterSource.hasValue(lowerCaseName)) {
 | 
			
		||||
					values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, lowerCaseName));
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					String propertyName = JdbcUtils.convertUnderscoreNameToPropertyName(column);
 | 
			
		||||
					if (parameterSource.hasValue(propertyName)) {
 | 
			
		||||
						values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, propertyName));
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						if (caseInsensitiveParameterNames.containsKey(lowerCaseName)) {
 | 
			
		||||
							values.add(
 | 
			
		||||
									SqlParameterSourceUtils.getTypedValue(parameterSource,
 | 
			
		||||
											(String) caseInsensitiveParameterNames.get(lowerCaseName)));
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							values.add(null);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return values;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match the provided column names and values with the list of columns used.
 | 
			
		||||
	 * @param inParameters the parameter names and values
 | 
			
		||||
	 */
 | 
			
		||||
	public List<Object> matchInParameterValuesWithInsertColumns(Map<String, Object> inParameters) {
 | 
			
		||||
		List<Object> values = new ArrayList<Object>();
 | 
			
		||||
		Map<String, Object> source = new HashMap<String, Object>();
 | 
			
		||||
		for (String key : inParameters.keySet()) {
 | 
			
		||||
			source.put(key.toLowerCase(), inParameters.get(key));
 | 
			
		||||
		}
 | 
			
		||||
		for (String column : tableColumns) {
 | 
			
		||||
			values.add(source.get(column.toLowerCase()));
 | 
			
		||||
		}
 | 
			
		||||
		return values;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Build the insert string based on configuration and metadata information
 | 
			
		||||
	 * @return the insert string to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public String createInsertString(String[] generatedKeyNames) {
 | 
			
		||||
		HashSet<String> keys = new HashSet<String>(generatedKeyNames.length);
 | 
			
		||||
		for (String key : generatedKeyNames) {
 | 
			
		||||
			keys.add(key.toUpperCase());
 | 
			
		||||
		}
 | 
			
		||||
		StringBuilder insertStatement = new StringBuilder();
 | 
			
		||||
		insertStatement.append("INSERT INTO ");
 | 
			
		||||
		if (this.getSchemaName() != null) {
 | 
			
		||||
			insertStatement.append(this.getSchemaName());
 | 
			
		||||
			insertStatement.append(".");
 | 
			
		||||
		}
 | 
			
		||||
		insertStatement.append(this.getTableName());
 | 
			
		||||
		insertStatement.append(" (");
 | 
			
		||||
		int columnCount = 0;
 | 
			
		||||
		for (String columnName : this.getTableColumns()) {
 | 
			
		||||
			if (!keys.contains(columnName.toUpperCase())) {
 | 
			
		||||
				columnCount++;
 | 
			
		||||
				if (columnCount > 1) {
 | 
			
		||||
					insertStatement.append(", ");
 | 
			
		||||
				}
 | 
			
		||||
				insertStatement.append(columnName);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		insertStatement.append(") VALUES(");
 | 
			
		||||
		if (columnCount < 1) {
 | 
			
		||||
			if (generatedKeyColumnsUsed) {
 | 
			
		||||
				logger.info("Unable to locate non-key columns for table '" +
 | 
			
		||||
						this.getTableName() + "' so an empty insert statement is generated");
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException("Unable to locate columns for table '" +
 | 
			
		||||
						this.getTableName() + "' so an insert statement can't be generated");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for (int i = 0; i < columnCount; i++) {
 | 
			
		||||
			if (i > 0) {
 | 
			
		||||
				insertStatement.append(", ");
 | 
			
		||||
			}
 | 
			
		||||
			insertStatement.append("?");
 | 
			
		||||
		}
 | 
			
		||||
		insertStatement.append(")");
 | 
			
		||||
		return insertStatement.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Build the array of {@link java.sql.Types} based on configuration and metadata information
 | 
			
		||||
	 * @return the array of types to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public int[] createInsertTypes() {
 | 
			
		||||
 | 
			
		||||
		int[] types = new int[this.getTableColumns().size()];
 | 
			
		||||
 | 
			
		||||
		List<TableParameterMetaData> parameters = this.metaDataProvider.getTableParameterMetaData();
 | 
			
		||||
		Map<String, TableParameterMetaData> parameterMap = new HashMap<String, TableParameterMetaData>(parameters.size());
 | 
			
		||||
		for (TableParameterMetaData tpmd : parameters) {
 | 
			
		||||
			parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int typeIndx = 0;
 | 
			
		||||
		for (String column : this.getTableColumns()) {
 | 
			
		||||
			if (column == null) {
 | 
			
		||||
				types[typeIndx] = SqlTypeValue.TYPE_UNKNOWN;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				TableParameterMetaData tpmd = parameterMap.get(column.toUpperCase());
 | 
			
		||||
				if (tpmd != null) {
 | 
			
		||||
					types[typeIndx] = tpmd.getSqlType();
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					types[typeIndx] = SqlTypeValue.TYPE_UNKNOWN;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			typeIndx++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return types;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface specifying the API to be implemented by a class providing table metedata.  This is intended for internal use
 | 
			
		||||
 * by the Simple JDBC classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public interface TableMetaDataProvider {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize using the database metedata provided
 | 
			
		||||
	 * @param databaseMetaData
 | 
			
		||||
	 * @throws SQLException
 | 
			
		||||
	 */
 | 
			
		||||
	void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize using provided database metadata, table and column information. This initalization can be
 | 
			
		||||
	 * turned off by specifying that column meta data should not be used.
 | 
			
		||||
	 * @param databaseMetaData used to retreive database specific information
 | 
			
		||||
	 * @param catalogName name of catalog to use or null
 | 
			
		||||
	 * @param schemaName name of schema name to use or null
 | 
			
		||||
	 * @param tableName name of the table
 | 
			
		||||
	 * @throws SQLException
 | 
			
		||||
	 */
 | 
			
		||||
	void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName)
 | 
			
		||||
			throws SQLException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the table name formatted based on metadata information. This could include altering the case.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param tableName
 | 
			
		||||
	 * @return table name formatted
 | 
			
		||||
	 */
 | 
			
		||||
	String tableNameToUse(String tableName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the catalog name formatted based on metadata information. This could include altering the case.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param catalogName
 | 
			
		||||
	 * @return catalog name formatted
 | 
			
		||||
	 */
 | 
			
		||||
	String catalogNameToUse(String catalogName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the schema name formatted based on metadata information. This could include altering the case.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param schemaName
 | 
			
		||||
	 * @return schema name formatted
 | 
			
		||||
	 */
 | 
			
		||||
	String schemaNameToUse(String schemaName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the catalog name passed in to match the meta data currently used.
 | 
			
		||||
	 * The reyurned value will be used for meta data lookups.  This could include alterig the case used or
 | 
			
		||||
	 * providing a base catalog if mone provided.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param catalogName
 | 
			
		||||
	 * @return catalog name to use
 | 
			
		||||
	 */
 | 
			
		||||
	String metaDataCatalogNameToUse(String catalogName) ;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide any modification of the schema name passed in to match the meta data currently used.
 | 
			
		||||
	 * The reyurned value will be used for meta data lookups.  This could include alterig the case used or
 | 
			
		||||
	 * providing a base schema if mone provided.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param schemaName
 | 
			
		||||
	 * @return schema name to use
 | 
			
		||||
	 */
 | 
			
		||||
	String metaDataSchemaNameToUse(String schemaName) ;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Are we using the meta data for the table columns?
 | 
			
		||||
	 */
 | 
			
		||||
 	boolean isTableColumnMetaDataUsed();
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support the JDBC 3.0 feature of retreiving generated keys
 | 
			
		||||
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}
 | 
			
		||||
	 */
 | 
			
		||||
 	boolean isGetGeneratedKeysSupported();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support a simple quey to retreive the generated key whe the JDBC 3.0 feature
 | 
			
		||||
	 * of retreiving generated keys is not supported
 | 
			
		||||
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}
 | 
			
		||||
	 */
 | 
			
		||||
 	boolean isGetGeneratedKeysSimulated();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the simple query to retreive a generated key
 | 
			
		||||
	 */
 | 
			
		||||
	String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does this database support a column name String array for retreiving generated keys
 | 
			
		||||
	 * {@link java.sql.Connection#createStruct(String, Object[])}
 | 
			
		||||
	 */
 | 
			
		||||
 	boolean isGeneratedKeysColumnNameArraySupported();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the table parameter metadata that is currently used.
 | 
			
		||||
	 * @return List of {@link TableParameterMetaData}
 | 
			
		||||
	 */
 | 
			
		||||
	List<TableParameterMetaData> getTableParameterMetaData();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessResourceFailureException;
 | 
			
		||||
import org.springframework.jdbc.support.DatabaseMetaDataCallback;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
import org.springframework.jdbc.support.MetaDataAccessException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Factory used to create a {@link TableMetaDataProvider} implementation based on the type of databse being used.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class TableMetaDataProviderFactory {
 | 
			
		||||
 | 
			
		||||
	/** Logger */
 | 
			
		||||
	private static final Log logger = LogFactory.getLog(TableMetaDataProviderFactory.class);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a TableMetaDataProvider based on the database metedata
 | 
			
		||||
	 * @param dataSource used to retrieve metedata
 | 
			
		||||
	 * @param context the class that holds configuration and metedata
 | 
			
		||||
	 * @return instance of the TableMetaDataProvider implementation to be used
 | 
			
		||||
	 */
 | 
			
		||||
	static public TableMetaDataProvider createMetaDataProvider(DataSource dataSource,
 | 
			
		||||
															 final TableMetaDataContext context) {
 | 
			
		||||
		try {
 | 
			
		||||
			return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData(
 | 
			
		||||
					dataSource, new DatabaseMetaDataCallback() {
 | 
			
		||||
 | 
			
		||||
				public Object processMetaData(DatabaseMetaData databaseMetaData)
 | 
			
		||||
						throws SQLException, MetaDataAccessException {
 | 
			
		||||
					String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
 | 
			
		||||
					boolean accessTableColumnMetaData = context.isAccessTableParameterMetaData();
 | 
			
		||||
					TableMetaDataProvider provider;
 | 
			
		||||
					if ("HSQL Database Engine".equals(databaseProductName)) {
 | 
			
		||||
						provider = new HsqlTableMetaDataProvider(databaseMetaData);
 | 
			
		||||
					}
 | 
			
		||||
					else if ("PostgreSQL".equals(databaseProductName)) {
 | 
			
		||||
						provider = new PostgresTableMetaDataProvider(databaseMetaData);
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						provider = new GenericTableMetaDataProvider(databaseMetaData);
 | 
			
		||||
					}
 | 
			
		||||
					if (logger.isDebugEnabled()) {
 | 
			
		||||
						logger.debug("Using " + provider.getClass().getName());
 | 
			
		||||
					}
 | 
			
		||||
					provider.initializeWithMetaData(databaseMetaData);
 | 
			
		||||
					if (accessTableColumnMetaData) {
 | 
			
		||||
						provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(), context.getSchemaName(), context.getTableName());
 | 
			
		||||
					}
 | 
			
		||||
					return provider;
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		} catch (MetaDataAccessException e) {
 | 
			
		||||
			throw new DataAccessResourceFailureException("Error retreiving database metadata", e);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.metadata;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Holder of metadata for a specific parameter that is used for table processing.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public class TableParameterMetaData {
 | 
			
		||||
 | 
			
		||||
	private final String parameterName;
 | 
			
		||||
 | 
			
		||||
	private final int sqlType;
 | 
			
		||||
 | 
			
		||||
	private final boolean nullable;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor taking all the properties.
 | 
			
		||||
	 */
 | 
			
		||||
	public TableParameterMetaData(String columnName, int sqlType, boolean nullable) {
 | 
			
		||||
		this.parameterName = columnName;
 | 
			
		||||
		this.sqlType = sqlType;
 | 
			
		||||
		this.nullable = nullable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the parameter name.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getParameterName() {
 | 
			
		||||
		return this.parameterName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the parameter SQL type.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getSqlType() {
 | 
			
		||||
		return this.sqlType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get whether the parameter/column is nullable.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isNullable() {
 | 
			
		||||
		return this.nullable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
<html>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
Context metadata abstraction for the configuration and execution of a stored procedure call.
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract base class for {@link SqlParameterSource} implementations.
 | 
			
		||||
 * Provides registration of SQL types per parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractSqlParameterSource implements SqlParameterSource {
 | 
			
		||||
 | 
			
		||||
	private final Map sqlTypes = new HashMap();
 | 
			
		||||
 | 
			
		||||
	private final Map typeNames = new HashMap();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Register a SQL type for the given parameter.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @param sqlType the SQL type of the parameter
 | 
			
		||||
	 */
 | 
			
		||||
	public void registerSqlType(String paramName, int sqlType) {
 | 
			
		||||
		Assert.notNull(paramName, "Parameter name must not be null");
 | 
			
		||||
		this.sqlTypes.put(paramName, new Integer(sqlType));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Register a SQL type for the given parameter.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @param typeName the type name of the parameter
 | 
			
		||||
	 */
 | 
			
		||||
	public void registerTypeName(String paramName, String typeName) {
 | 
			
		||||
		Assert.notNull(paramName, "Parameter name must not be null");
 | 
			
		||||
		this.typeNames.put(paramName, typeName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQL type for the given parameter, if registered.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @return the SQL type of the parameter,
 | 
			
		||||
	 * or <code>TYPE_UNKNOWN</code> if not registered
 | 
			
		||||
	 */
 | 
			
		||||
	public int getSqlType(String paramName) {
 | 
			
		||||
		Assert.notNull(paramName, "Parameter name must not be null");
 | 
			
		||||
		Integer sqlType = (Integer) this.sqlTypes.get(paramName);
 | 
			
		||||
		if (sqlType != null) {
 | 
			
		||||
			return sqlType.intValue();
 | 
			
		||||
		}
 | 
			
		||||
		return TYPE_UNKNOWN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the type name for the given parameter, if registered.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @return the type name of the parameter,
 | 
			
		||||
	 * or <code>null</code> if not registered
 | 
			
		||||
	 */
 | 
			
		||||
	public String getTypeName(String paramName) {
 | 
			
		||||
		Assert.notNull(paramName, "Parameter name must not be null");
 | 
			
		||||
		return (String) this.typeNames.get(paramName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,103 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.beans.PropertyDescriptor;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.BeanWrapper;
 | 
			
		||||
import org.springframework.beans.NotReadablePropertyException;
 | 
			
		||||
import org.springframework.beans.PropertyAccessor;
 | 
			
		||||
import org.springframework.beans.PropertyAccessorFactory;
 | 
			
		||||
import org.springframework.jdbc.core.StatementCreatorUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link SqlParameterSource} implementation that obtains parameter values
 | 
			
		||||
 * from bean properties of a given JavaBean object. The names of the bean
 | 
			
		||||
 * properties have to match the parameter names.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Uses a Spring BeanWrapper for bean property access underneath.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see NamedParameterJdbcTemplate
 | 
			
		||||
 * @see org.springframework.beans.BeanWrapper
 | 
			
		||||
 */
 | 
			
		||||
public class BeanPropertySqlParameterSource extends AbstractSqlParameterSource {
 | 
			
		||||
 | 
			
		||||
	private final BeanWrapper beanWrapper;
 | 
			
		||||
 | 
			
		||||
	private String[] propertyNames;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BeanPropertySqlParameterSource for the given bean.
 | 
			
		||||
	 * @param object the bean instance to wrap
 | 
			
		||||
	 */
 | 
			
		||||
	public BeanPropertySqlParameterSource(Object object) {
 | 
			
		||||
		this.beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(object);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public boolean hasValue(String paramName) {
 | 
			
		||||
		return this.beanWrapper.isReadableProperty(paramName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object getValue(String paramName) throws IllegalArgumentException {
 | 
			
		||||
		try {
 | 
			
		||||
			return this.beanWrapper.getPropertyValue(paramName);
 | 
			
		||||
		}
 | 
			
		||||
		catch (NotReadablePropertyException ex) {
 | 
			
		||||
			throw new IllegalArgumentException(ex.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Provide access to the property names of the wrapped bean.
 | 
			
		||||
	 * Uses support provided in the {@link PropertyAccessor} interface.
 | 
			
		||||
	 * @return an array containing all the known property names
 | 
			
		||||
	 */
 | 
			
		||||
	public String[] getReadablePropertyNames() {
 | 
			
		||||
		if (this.propertyNames == null) {
 | 
			
		||||
			List names = new ArrayList();
 | 
			
		||||
			PropertyDescriptor[] props = this.beanWrapper.getPropertyDescriptors();
 | 
			
		||||
			for (int i = 0; i < props.length; i++) {
 | 
			
		||||
				if (this.beanWrapper.isReadableProperty(props[i].getName())) {
 | 
			
		||||
					names.add(props[i].getName());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			this.propertyNames = (String[]) names.toArray(new String[names.size()]);
 | 
			
		||||
		}
 | 
			
		||||
		return this.propertyNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Derives a default SQL type from the corresponding property type.
 | 
			
		||||
	 * @see org.springframework.jdbc.core.StatementCreatorUtils#javaTypeToSqlParameterType
 | 
			
		||||
	 */
 | 
			
		||||
	public int getSqlType(String paramName) {
 | 
			
		||||
		int sqlType = super.getSqlType(paramName);
 | 
			
		||||
		if (sqlType != TYPE_UNKNOWN) {
 | 
			
		||||
			return sqlType;
 | 
			
		||||
		}
 | 
			
		||||
		Class propType = this.beanWrapper.getPropertyType(paramName);
 | 
			
		||||
		return StatementCreatorUtils.javaTypeToSqlParameterType(propType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,165 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameterValue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link SqlParameterSource} implementation that holds a given Map of parameters.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This class is intended for passing in a simple Map of parameter values
 | 
			
		||||
 * to the methods of the {@link NamedParameterJdbcTemplate} class.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The <code>addValue</code> methods on this class will make adding several
 | 
			
		||||
 * values easier. The methods return a reference to the {@link MapSqlParameterSource}
 | 
			
		||||
 * itself, so you can chain several method calls together within a single statement.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see #addValue(String, Object)
 | 
			
		||||
 * @see #addValue(String, Object, int)
 | 
			
		||||
 * @see #registerSqlType
 | 
			
		||||
 * @see NamedParameterJdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class MapSqlParameterSource extends AbstractSqlParameterSource {
 | 
			
		||||
 | 
			
		||||
	private final Map values = new HashMap();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create an empty MapSqlParameterSource,
 | 
			
		||||
	 * with values to be added via <code>addValue</code>.
 | 
			
		||||
	 * @see #addValue(String, Object)
 | 
			
		||||
	 */
 | 
			
		||||
	public MapSqlParameterSource() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new MapSqlParameterSource, with one value
 | 
			
		||||
	 * comprised of the supplied arguments.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @param value the value of the parameter
 | 
			
		||||
	 * @see #addValue(String, Object)
 | 
			
		||||
	 */
 | 
			
		||||
	public MapSqlParameterSource(String paramName, Object value) {
 | 
			
		||||
		addValue(paramName, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new MapSqlParameterSource based on a Map.
 | 
			
		||||
	 * @param values a Map holding existing parameter values (can be <code>null</code>)
 | 
			
		||||
	 */
 | 
			
		||||
	public MapSqlParameterSource(Map values) {
 | 
			
		||||
		addValues(values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a parameter to this parameter source.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @param value the value of the parameter
 | 
			
		||||
	 * @return a reference to this parameter source,
 | 
			
		||||
	 * so it's possible to chain several calls together
 | 
			
		||||
	 */
 | 
			
		||||
	public MapSqlParameterSource addValue(String paramName, Object value) {
 | 
			
		||||
		Assert.notNull(paramName, "Parameter name must not be null");
 | 
			
		||||
		this.values.put(paramName, value);
 | 
			
		||||
		if (value != null && value instanceof SqlParameterValue) {
 | 
			
		||||
			registerSqlType(paramName, ((SqlParameterValue)value).getSqlType());
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a parameter to this parameter source.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @param value the value of the parameter
 | 
			
		||||
	 * @param sqlType the SQL type of the parameter
 | 
			
		||||
	 * @return a reference to this parameter source,
 | 
			
		||||
	 * so it's possible to chain several calls together
 | 
			
		||||
	 */
 | 
			
		||||
	public MapSqlParameterSource addValue(String paramName, Object value, int sqlType) {
 | 
			
		||||
		Assert.notNull(paramName, "Parameter name must not be null");
 | 
			
		||||
		this.values.put(paramName, value);
 | 
			
		||||
		registerSqlType(paramName, sqlType);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a parameter to this parameter source.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @param value the value of the parameter
 | 
			
		||||
	 * @param sqlType the SQL type of the parameter
 | 
			
		||||
	 * @param typeName the type name of the parameter
 | 
			
		||||
	 * @return a reference to this parameter source,
 | 
			
		||||
	 * so it's possible to chain several calls together
 | 
			
		||||
	 */
 | 
			
		||||
	public MapSqlParameterSource addValue(String paramName, Object value, int sqlType, String typeName) {
 | 
			
		||||
		Assert.notNull(paramName, "Parameter name must not be null");
 | 
			
		||||
		this.values.put(paramName, value);
 | 
			
		||||
		registerSqlType(paramName, sqlType);
 | 
			
		||||
		registerTypeName(paramName, typeName);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a Map of parameters to this parameter source.
 | 
			
		||||
	 * @param values a Map holding existing parameter values (can be <code>null</code>)
 | 
			
		||||
	 * @return a reference to this parameter source,
 | 
			
		||||
	 * so it's possible to chain several calls together
 | 
			
		||||
	 */
 | 
			
		||||
	public MapSqlParameterSource addValues(Map values) {
 | 
			
		||||
		if (values != null) {
 | 
			
		||||
			this.values.putAll(values);
 | 
			
		||||
			for (Iterator iter = values.keySet().iterator(); iter.hasNext();) {
 | 
			
		||||
				Object k =  iter.next();
 | 
			
		||||
				Object o = values.get(k);
 | 
			
		||||
				if (o != null && k instanceof String && o instanceof SqlParameterValue) {
 | 
			
		||||
					registerSqlType((String)k, ((SqlParameterValue)o).getSqlType());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Expose the current parameter values as read-only Map.
 | 
			
		||||
	 */
 | 
			
		||||
	public Map getValues() {
 | 
			
		||||
		return Collections.unmodifiableMap(this.values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public boolean hasValue(String paramName) {
 | 
			
		||||
		return this.values.containsKey(paramName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object getValue(String paramName) {
 | 
			
		||||
		if (!hasValue(paramName)) {
 | 
			
		||||
			throw new IllegalArgumentException("No value registered for key '" + paramName + "'");
 | 
			
		||||
		}
 | 
			
		||||
		return this.values.get(paramName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.support.JdbcDaoSupport;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of JdbcDaoSupport that exposes a NamedParameterJdbcTemplate as well.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see NamedParameterJdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class NamedParameterJdbcDaoSupport extends JdbcDaoSupport {
 | 
			
		||||
	
 | 
			
		||||
	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a NamedParameterJdbcTemplate based on the configured JdbcTemplate.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void initTemplateConfig() {
 | 
			
		||||
		this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a NamedParameterJdbcTemplate wrapping the configured JdbcTemplate.
 | 
			
		||||
	 */
 | 
			
		||||
	public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
 | 
			
		||||
	  return namedParameterJdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,492 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcOperations;
 | 
			
		||||
import org.springframework.jdbc.core.PreparedStatementCallback;
 | 
			
		||||
import org.springframework.jdbc.core.ResultSetExtractor;
 | 
			
		||||
import org.springframework.jdbc.core.RowCallbackHandler;
 | 
			
		||||
import org.springframework.jdbc.core.RowMapper;
 | 
			
		||||
import org.springframework.jdbc.support.KeyHolder;
 | 
			
		||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface specifying a basic set of JDBC operations allowing the use
 | 
			
		||||
 * of named parameters rather than the traditional '?' placeholders.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This is an alternative to the classic
 | 
			
		||||
 * {@link org.springframework.jdbc.core.JdbcOperations} interface,
 | 
			
		||||
 * implemented by {@link NamedParameterJdbcTemplate}. This interface is not
 | 
			
		||||
 * often used directly, but provides a useful option to enhance testability,
 | 
			
		||||
 * as it can easily be mocked or stubbed.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see NamedParameterJdbcTemplate
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcOperations
 | 
			
		||||
 */
 | 
			
		||||
public interface NamedParameterJdbcOperations {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Expose the classic Spring JdbcTemplate to allow invocation of
 | 
			
		||||
	 * classic JDBC operations.
 | 
			
		||||
	 */
 | 
			
		||||
	JdbcOperations getJdbcOperations();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC PreparedStatement. This allows for implementing arbitrary
 | 
			
		||||
	 * data access operations on a single Statement, within Spring's managed
 | 
			
		||||
	 * JDBC environment: that is, participating in Spring-managed transactions
 | 
			
		||||
	 * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param sql SQL to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @param action callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback action)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a JDBC data access operation, implemented as callback action
 | 
			
		||||
	 * working on a JDBC PreparedStatement. This allows for implementing arbitrary
 | 
			
		||||
	 * data access operations on a single Statement, within Spring's managed
 | 
			
		||||
	 * JDBC environment: that is, participating in Spring-managed transactions
 | 
			
		||||
	 * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
 | 
			
		||||
	 * <p>The callback action can return a result object, for example a
 | 
			
		||||
	 * domain object or a collection of domain objects.
 | 
			
		||||
	 * @param sql SQL to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param action callback object that specifies the action
 | 
			
		||||
	 * @return a result object returned by the action, or <code>null</code>
 | 
			
		||||
	 * @throws DataAccessException if there is any problem
 | 
			
		||||
	 */
 | 
			
		||||
	Object execute(String sql, Map paramMap, PreparedStatementCallback action)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, reading the ResultSet with a
 | 
			
		||||
	 * ResultSetExtractor.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @param rse object that will extract results
 | 
			
		||||
	 * @return an arbitrary result object, as returned by the ResultSetExtractor
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	Object query(String sql, SqlParameterSource paramSource, ResultSetExtractor rse)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, reading the ResultSet with a
 | 
			
		||||
	 * ResultSetExtractor.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param rse object that will extract results
 | 
			
		||||
	 * @return an arbitrary result object, as returned by the ResultSetExtractor
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	Object query(String sql, Map paramMap, ResultSetExtractor rse) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list of
 | 
			
		||||
	 * arguments to bind to the query, reading the ResultSet on a per-row basis
 | 
			
		||||
	 * with a RowCallbackHandler.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @param rch object that will extract results, one row at a time
 | 
			
		||||
	 * @throws DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	void query(String sql, SqlParameterSource paramSource, RowCallbackHandler rch)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list of
 | 
			
		||||
	 * arguments to bind to the query, reading the ResultSet on a per-row basis
 | 
			
		||||
	 * with a RowCallbackHandler.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param rch object that will extract results, one row at a time
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	void query(String sql, Map paramMap, RowCallbackHandler rch) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping each row to a Java object
 | 
			
		||||
	 * via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the result List, containing mapped objects
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	List query(String sql, SqlParameterSource paramSource, RowMapper rowMapper)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping each row to a Java object
 | 
			
		||||
	 * via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the result List, containing mapped objects
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	List query(String sql, Map paramMap, RowMapper rowMapper) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping a single result row to a
 | 
			
		||||
	 * Java object via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the single mapped object
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, SqlParameterSource paramSource, RowMapper rowMapper)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a list
 | 
			
		||||
	 * of arguments to bind to the query, mapping a single result row to a
 | 
			
		||||
	 * Java object via a RowMapper.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param rowMapper object that will map one object per row
 | 
			
		||||
	 * @return the single mapped object
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, Map paramMap, RowMapper rowMapper) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result object.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query; the returned
 | 
			
		||||
	 * result will be directly mapped to the corresponding object type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @param requiredType the type that the result object is expected to match
 | 
			
		||||
	 * @return the result object of the required type, or <code>null</code> in case of SQL NULL
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Class)
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, SqlParameterSource paramSource, Class requiredType)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result object.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query; the returned
 | 
			
		||||
	 * result will be directly mapped to the corresponding object type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param requiredType the type that the result object is expected to match
 | 
			
		||||
	 * @return the result object of the required type, or <code>null</code> in case of SQL NULL
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Class)
 | 
			
		||||
	 */
 | 
			
		||||
	Object queryForObject(String sql, Map paramMap, Class requiredType) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result Map.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @return the result Map (one entry for each column, using the column name as the key)
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String)
 | 
			
		||||
	 * @see org.springframework.jdbc.core.ColumnMapRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	Map queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result Map.
 | 
			
		||||
	 * The queryForMap() methods defined by this interface are appropriate
 | 
			
		||||
	 * when you don't have a domain model. Otherwise, consider using
 | 
			
		||||
	 * one of the queryForObject() methods.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @return the result Map (one entry for each column, using the column name as the key)
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String)
 | 
			
		||||
	 * @see org.springframework.jdbc.core.ColumnMapRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	Map queryForMap(String sql, Map paramMap) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in a long value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in a long value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @return the long value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForLong(String)
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql, SqlParameterSource paramSource) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in a long value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in a long value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @return the long value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * if the query does not return exactly one row, or does not return exactly
 | 
			
		||||
	 * one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForLong(String)
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql, Map paramMap) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in an int value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in an int value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @return the int value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForInt(String)
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql, SqlParameterSource paramSource) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, resulting in an int value.
 | 
			
		||||
	 * <p>The query is expected to be a single row/single column query that
 | 
			
		||||
	 * results in an int value.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @return the int value, or 0 in case of SQL NULL
 | 
			
		||||
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the query does not return
 | 
			
		||||
	 * exactly one row, or does not return exactly one column in that row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForInt(String)
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql, Map paramMap) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * result objects, each of them matching the specified element type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @param elementType the required type of element in the result list
 | 
			
		||||
	 * (for example, <code>Integer.class</code>)
 | 
			
		||||
	 * @return a List of objects that match the specified element type
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Class)
 | 
			
		||||
	 * @see org.springframework.jdbc.core.SingleColumnRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, SqlParameterSource paramSource, Class elementType)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * result objects, each of them matching the specified element type.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @param elementType the required type of element in the result list
 | 
			
		||||
	 * (for example, <code>Integer.class</code>)
 | 
			
		||||
	 * @return a List of objects that match the specified element type
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Class)
 | 
			
		||||
	 * @see org.springframework.jdbc.core.SingleColumnRowMapper
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, Map paramMap, Class elementType) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * Maps (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * Thus  Each element in the list will be of the form returned by this interface's
 | 
			
		||||
	 * queryForMap() methods.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @return a List that contains a Map per row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String)
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, SqlParameterSource paramSource) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a result list.
 | 
			
		||||
	 * <p>The results will be mapped to a List (one entry for each row) of
 | 
			
		||||
	 * Maps (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * Each element in the list will be of the form returned by this interface's
 | 
			
		||||
	 * queryForMap() methods.
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @return a List that contains a Map per row
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if the query fails
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String)
 | 
			
		||||
	 */
 | 
			
		||||
	List queryForList(String sql, Map paramMap) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a SqlRowSet.
 | 
			
		||||
	 * <p>The results will be mapped to an SqlRowSet which holds the data in a
 | 
			
		||||
	 * disconnected fashion. This wrapper will translate any SQLExceptions thrown.
 | 
			
		||||
	 * <p>Note that that, for the default implementation, JDBC RowSet support needs to
 | 
			
		||||
	 * be available at runtime: by default, Sun's <code>com.sun.rowset.CachedRowSetImpl</code>
 | 
			
		||||
	 * class is used, which is part of JDK 1.5+ and also available separately as part of
 | 
			
		||||
	 * Sun's JDBC RowSet Implementations download (rowset.jar).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind to the query
 | 
			
		||||
	 * @return a SqlRowSet representation (possibly a wrapper around a
 | 
			
		||||
	 * <code>javax.sql.rowset.CachedRowSet</code>)
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForRowSet(String)
 | 
			
		||||
	 * @see org.springframework.jdbc.core.SqlRowSetResultSetExtractor
 | 
			
		||||
	 * @see javax.sql.rowset.CachedRowSet
 | 
			
		||||
	 */
 | 
			
		||||
	SqlRowSet queryForRowSet(String sql, SqlParameterSource paramSource) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query given SQL to create a prepared statement from SQL and a
 | 
			
		||||
	 * list of arguments to bind to the query, expecting a SqlRowSet.
 | 
			
		||||
	 * <p>The results will be mapped to an SqlRowSet which holds the data in a
 | 
			
		||||
	 * disconnected fashion. This wrapper will translate any SQLExceptions thrown.
 | 
			
		||||
	 * <p>Note that that, for the default implementation, JDBC RowSet support needs to
 | 
			
		||||
	 * be available at runtime: by default, Sun's <code>com.sun.rowset.CachedRowSetImpl</code>
 | 
			
		||||
	 * class is used, which is part of JDK 1.5+ and also available separately as part of
 | 
			
		||||
	 * Sun's JDBC RowSet Implementations download (rowset.jar).
 | 
			
		||||
	 * @param sql SQL query to execute
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @return a SqlRowSet representation (possibly a wrapper around a
 | 
			
		||||
	 * <code>javax.sql.rowset.CachedRowSet</code>)
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if there is any problem executing the query
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#queryForRowSet(String)
 | 
			
		||||
	 * @see org.springframework.jdbc.core.SqlRowSetResultSetExtractor
 | 
			
		||||
	 * @see javax.sql.rowset.CachedRowSet
 | 
			
		||||
	 */
 | 
			
		||||
	SqlRowSet queryForRowSet(String sql, Map paramMap) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue an update via a prepared statement, binding the given arguments.
 | 
			
		||||
	 * @param sql SQL containing named parameters
 | 
			
		||||
	 * @param paramSource container of arguments and SQL types to bind to the query
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, SqlParameterSource paramSource) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue an update via a prepared statement, binding the given arguments.
 | 
			
		||||
	 * @param sql SQL containing named parameters
 | 
			
		||||
	 * @param paramMap map of parameters to bind to the query
 | 
			
		||||
	 * (leaving it to the PreparedStatement to guess the corresponding SQL type)
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, Map paramMap) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue an update via a prepared statement, binding the given arguments,
 | 
			
		||||
	 * returning generated keys.
 | 
			
		||||
	 * @param sql SQL containing named parameters
 | 
			
		||||
	 * @param paramSource container of arguments and SQL types to bind to the query
 | 
			
		||||
	 * @param generatedKeyHolder KeyHolder that will hold the generated keys
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 * @see MapSqlParameterSource
 | 
			
		||||
	 * @see org.springframework.jdbc.support.GeneratedKeyHolder
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Issue an update via a prepared statement, binding the given arguments,
 | 
			
		||||
	 * returning generated keys.
 | 
			
		||||
	 * @param sql SQL containing named parameters
 | 
			
		||||
	 * @param paramSource container of arguments and SQL types to bind to the query
 | 
			
		||||
	 * @param generatedKeyHolder KeyHolder that will hold the generated keys
 | 
			
		||||
	 * @param keyColumnNames names of the columns that will have keys generated for them
 | 
			
		||||
	 * @return the number of rows affected
 | 
			
		||||
	 * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update
 | 
			
		||||
	 * @see MapSqlParameterSource
 | 
			
		||||
	 * @see org.springframework.jdbc.support.GeneratedKeyHolder
 | 
			
		||||
	 */
 | 
			
		||||
	int update(
 | 
			
		||||
			String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder, String[] keyColumnNames)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,278 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.dao.support.DataAccessUtils;
 | 
			
		||||
import org.springframework.jdbc.core.ColumnMapRowMapper;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcOperations;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.core.PreparedStatementCallback;
 | 
			
		||||
import org.springframework.jdbc.core.PreparedStatementCreator;
 | 
			
		||||
import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
 | 
			
		||||
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.SqlRowSetResultSetExtractor;
 | 
			
		||||
import org.springframework.jdbc.support.KeyHolder;
 | 
			
		||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Template class with a basic set of JDBC operations, allowing the use
 | 
			
		||||
 * of named parameters rather than traditional '?' placeholders.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This class delegates to a wrapped {@link #getJdbcOperations() JdbcTemplate}
 | 
			
		||||
 * once the substitution from named parameters to JDBC style '?' placeholders is
 | 
			
		||||
 * done at execution time. It also allows for expanding a {@link java.util.List}
 | 
			
		||||
 * of values to the appropriate number of placeholders.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The underlying {@link org.springframework.jdbc.core.JdbcTemplate} is
 | 
			
		||||
 * exposed to allow for convenient access to the traditional
 | 
			
		||||
 * {@link org.springframework.jdbc.core.JdbcTemplate} methods.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see NamedParameterJdbcOperations
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations {
 | 
			
		||||
 | 
			
		||||
	/** The JdbcTemplate we are wrapping */
 | 
			
		||||
	private final JdbcOperations classicJdbcTemplate;
 | 
			
		||||
 | 
			
		||||
	/** Map of original SQL String to ParsedSql representation */
 | 
			
		||||
	private final Map parsedSqlCache = new HashMap();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new NamedParameterJdbcTemplate for the given {@link DataSource}.
 | 
			
		||||
	 * <p>Creates a classic Spring {@link org.springframework.jdbc.core.JdbcTemplate} and wraps it.
 | 
			
		||||
	 * @param dataSource the JDBC DataSource to access
 | 
			
		||||
	 */
 | 
			
		||||
	public NamedParameterJdbcTemplate(DataSource dataSource) {
 | 
			
		||||
		Assert.notNull(dataSource, "The [dataSource] argument cannot be null.");
 | 
			
		||||
		this.classicJdbcTemplate = new JdbcTemplate(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new NamedParameterJdbcTemplate for the given classic
 | 
			
		||||
	 * Spring {@link org.springframework.jdbc.core.JdbcTemplate}.
 | 
			
		||||
	 * @param classicJdbcTemplate the classic Spring JdbcTemplate to wrap
 | 
			
		||||
	 */
 | 
			
		||||
	public NamedParameterJdbcTemplate(JdbcOperations classicJdbcTemplate) {
 | 
			
		||||
		Assert.notNull(classicJdbcTemplate, "JdbcTemplate must not be null");
 | 
			
		||||
		this.classicJdbcTemplate = classicJdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Expose the classic Spring JdbcTemplate to allow invocation of
 | 
			
		||||
	 * less commonly used methods.
 | 
			
		||||
	 */
 | 
			
		||||
	public JdbcOperations getJdbcOperations() {
 | 
			
		||||
		return this.classicJdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public Object execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback action)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		return getJdbcOperations().execute(getPreparedStatementCreator(sql, paramSource), action);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object execute(String sql, Map paramMap, PreparedStatementCallback action) throws DataAccessException {
 | 
			
		||||
		return execute(sql, new MapSqlParameterSource(paramMap), action);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object query(String sql, SqlParameterSource paramSource, ResultSetExtractor rse)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rse);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object query(String sql, Map paramMap, ResultSetExtractor rse) throws DataAccessException {
 | 
			
		||||
		return query(sql, new MapSqlParameterSource(paramMap), rse);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void query(String sql, SqlParameterSource paramSource, RowCallbackHandler rch)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void query(String sql, Map paramMap, RowCallbackHandler rch) throws DataAccessException {
 | 
			
		||||
		query(sql, new MapSqlParameterSource(paramMap), rch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List query(String sql, SqlParameterSource paramSource, RowMapper rowMapper)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rowMapper);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List query(String sql, Map paramMap, RowMapper rowMapper) throws DataAccessException {
 | 
			
		||||
		return query(sql, new MapSqlParameterSource(paramMap), rowMapper);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object queryForObject(String sql, SqlParameterSource paramSource, RowMapper rowMapper)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		List results = getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rowMapper);
 | 
			
		||||
		return DataAccessUtils.requiredSingleResult(results);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object queryForObject(String sql, Map paramMap, RowMapper rowMapper) throws DataAccessException {
 | 
			
		||||
		return queryForObject(sql, new MapSqlParameterSource(paramMap), rowMapper);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object queryForObject(String sql, SqlParameterSource paramSource, Class requiredType)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		return queryForObject(sql, paramSource, new SingleColumnRowMapper(requiredType));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Object queryForObject(String sql, Map paramMap, Class requiredType) throws DataAccessException {
 | 
			
		||||
		return queryForObject(sql, paramMap, new SingleColumnRowMapper(requiredType));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Map queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException {
 | 
			
		||||
		return (Map) queryForObject(sql, paramSource, new ColumnMapRowMapper());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Map queryForMap(String sql, Map paramMap) throws DataAccessException {
 | 
			
		||||
		return (Map) queryForObject(sql, paramMap, new ColumnMapRowMapper());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public long queryForLong(String sql, SqlParameterSource paramSource) throws DataAccessException {
 | 
			
		||||
		Number number = (Number) queryForObject(sql, paramSource, Number.class);
 | 
			
		||||
		return (number != null ? number.longValue() : 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public long queryForLong(String sql, Map paramMap) throws DataAccessException {
 | 
			
		||||
		return queryForLong(sql, new MapSqlParameterSource(paramMap));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int queryForInt(String sql, SqlParameterSource paramSource) throws DataAccessException {
 | 
			
		||||
		Number number = (Number) queryForObject(sql, paramSource, Number.class);
 | 
			
		||||
		return (number != null ? number.intValue() : 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int queryForInt(String sql, Map paramMap) throws DataAccessException {
 | 
			
		||||
		return queryForInt(sql, new MapSqlParameterSource(paramMap));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List queryForList(String sql, SqlParameterSource paramSource, Class elementType)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
		return query(sql, paramSource, new SingleColumnRowMapper(elementType));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List queryForList(String sql, Map paramMap, Class elementType) throws DataAccessException {
 | 
			
		||||
		return queryForList(sql, new MapSqlParameterSource(paramMap), elementType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List queryForList(String sql, SqlParameterSource paramSource) throws DataAccessException {
 | 
			
		||||
		return query(sql, paramSource, new ColumnMapRowMapper());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public List queryForList(String sql, Map paramMap) throws DataAccessException {
 | 
			
		||||
		return queryForList(sql, new MapSqlParameterSource(paramMap));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SqlRowSet queryForRowSet(String sql, SqlParameterSource paramSource) throws DataAccessException {
 | 
			
		||||
		return (SqlRowSet) getJdbcOperations().query(
 | 
			
		||||
				getPreparedStatementCreator(sql, paramSource), new SqlRowSetResultSetExtractor());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SqlRowSet queryForRowSet(String sql, Map paramMap) throws DataAccessException {
 | 
			
		||||
		return queryForRowSet(sql, new MapSqlParameterSource(paramMap));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int update(String sql, SqlParameterSource paramSource) throws DataAccessException {
 | 
			
		||||
		return getJdbcOperations().update(getPreparedStatementCreator(sql, paramSource));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int update(String sql, Map paramMap) throws DataAccessException {
 | 
			
		||||
		return update(sql, new MapSqlParameterSource(paramMap));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		return update(sql, paramSource, generatedKeyHolder, null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int update(
 | 
			
		||||
			String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder, String[] keyColumnNames)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
 | 
			
		||||
		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);
 | 
			
		||||
		if (keyColumnNames != null) {
 | 
			
		||||
			pscf.setGeneratedKeysColumnNames(keyColumnNames);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			pscf.setReturnGeneratedKeys(true);
 | 
			
		||||
		}
 | 
			
		||||
		return getJdbcOperations().update(pscf.newPreparedStatementCreator(params), generatedKeyHolder);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Build a PreparedStatementCreator based on the given SQL and named parameters.
 | 
			
		||||
	 * <p>Note: Not used for the <code>update</code> variant with generated key handling.
 | 
			
		||||
	 * @param sql SQL to execute
 | 
			
		||||
	 * @param paramSource container of arguments to bind
 | 
			
		||||
	 * @return the corresponding PreparedStatementCreator
 | 
			
		||||
	 */
 | 
			
		||||
	protected PreparedStatementCreator getPreparedStatementCreator(String sql, SqlParameterSource paramSource) {
 | 
			
		||||
		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);
 | 
			
		||||
		return pscf.newPreparedStatementCreator(params);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Obtain a parsed representation of the given SQL statement.
 | 
			
		||||
	 * @param sql the original SQL
 | 
			
		||||
	 * @return a representation of the parsed SQL statement
 | 
			
		||||
	 */
 | 
			
		||||
	protected ParsedSql getParsedSql(String sql) {
 | 
			
		||||
		synchronized (this.parsedSqlCache) {
 | 
			
		||||
			ParsedSql parsedSql = (ParsedSql) this.parsedSqlCache.get(sql);
 | 
			
		||||
			if (parsedSql == null) {
 | 
			
		||||
				parsedSql = NamedParameterUtils.parseSqlStatement(sql);
 | 
			
		||||
				this.parsedSqlCache.put(sql, parsedSql);
 | 
			
		||||
			}
 | 
			
		||||
			return parsedSql;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,386 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameterValue;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper methods for named parameter parsing.
 | 
			
		||||
 * Only intended for internal use within Spring's JDBC framework.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 */
 | 
			
		||||
public abstract class NamedParameterUtils {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set of characters that qualify as parameter separators,
 | 
			
		||||
	 * indicating that a parameter name in a SQL String has ended.
 | 
			
		||||
	 */
 | 
			
		||||
	private static final char[] PARAMETER_SEPARATORS =
 | 
			
		||||
			new char[] {'"', '\'', ':', '&', ',', ';', '(', ')', '|', '=', '+', '-', '*', '%', '/', '\\', '<', '>', '^'};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set of characters that qualify as comment or quotes starting characters.
 | 
			
		||||
	 */
 | 
			
		||||
	private static final String[] START_SKIP =
 | 
			
		||||
			new String[] {"'", "\"", "--", "/*"};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set of characters that at are the corresponding comment or quotes ending characters.
 | 
			
		||||
	 */
 | 
			
		||||
	private static final String[] STOP_SKIP =
 | 
			
		||||
			new String[] {"'", "\"", "\n", "*/"};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Core methods used by NamedParameterJdbcTemplate and SqlQuery/SqlUpdate
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Parse the SQL statement and locate any placeholders or named parameters.
 | 
			
		||||
	 * Named parameters are substituted for a JDBC placeholder.
 | 
			
		||||
	 * @param sql the SQL statement
 | 
			
		||||
	 * @return the parsed statement, represented as ParsedSql instance
 | 
			
		||||
	 */
 | 
			
		||||
	public static ParsedSql parseSqlStatement(String sql) {
 | 
			
		||||
		Assert.notNull(sql, "SQL must not be null");
 | 
			
		||||
 | 
			
		||||
		Set namedParameters = new HashSet();
 | 
			
		||||
		ParsedSql parsedSql = new ParsedSql(sql);
 | 
			
		||||
 | 
			
		||||
		char[] statement = sql.toCharArray();
 | 
			
		||||
		int namedParameterCount = 0;
 | 
			
		||||
		int unnamedParameterCount = 0;
 | 
			
		||||
		int totalParameterCount = 0;
 | 
			
		||||
 | 
			
		||||
		int i = 0;
 | 
			
		||||
		while (i < statement.length) {
 | 
			
		||||
			int skipToPosition = skipCommentsAndQuotes(statement, i);
 | 
			
		||||
			if (i != skipToPosition) {
 | 
			
		||||
				if (skipToPosition >= statement.length) {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				i = skipToPosition;
 | 
			
		||||
			}
 | 
			
		||||
			char c = statement[i];
 | 
			
		||||
			if (c == ':' || c == '&') {
 | 
			
		||||
				int j = i + 1;
 | 
			
		||||
				if (j < statement.length && statement[j] == ':' && c == ':') {
 | 
			
		||||
					// Postgres-style "::" casting operator - to be skipped.
 | 
			
		||||
					i = i + 2;
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				while (j < statement.length && !isParameterSeparator(statement[j])) {
 | 
			
		||||
					j++;
 | 
			
		||||
				}
 | 
			
		||||
				if (j - i > 1) {
 | 
			
		||||
					String parameter = sql.substring(i + 1, j);
 | 
			
		||||
					if (!namedParameters.contains(parameter)) {
 | 
			
		||||
						namedParameters.add(parameter);
 | 
			
		||||
						namedParameterCount++;
 | 
			
		||||
					}
 | 
			
		||||
					parsedSql.addNamedParameter(parameter, i, j);
 | 
			
		||||
					totalParameterCount++;
 | 
			
		||||
				}
 | 
			
		||||
				i = j - 1;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (c == '?') {
 | 
			
		||||
					unnamedParameterCount++;
 | 
			
		||||
					totalParameterCount++;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			i++;
 | 
			
		||||
		}
 | 
			
		||||
		parsedSql.setNamedParameterCount(namedParameterCount);
 | 
			
		||||
		parsedSql.setUnnamedParameterCount(unnamedParameterCount);
 | 
			
		||||
		parsedSql.setTotalParameterCount(totalParameterCount);
 | 
			
		||||
		return parsedSql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Skip over comments and quoted names present in an SQL statement
 | 
			
		||||
	 * @param statement character array containing SQL statement
 | 
			
		||||
	 * @param position current position of statement
 | 
			
		||||
	 * @return next position to process after any comments or quotes are skipped
 | 
			
		||||
	 */
 | 
			
		||||
	private static int skipCommentsAndQuotes(char[] statement, int position) {
 | 
			
		||||
		for (int i = 0; i < START_SKIP.length; i++) {
 | 
			
		||||
			if (statement[position] == START_SKIP[i].charAt(0)) {
 | 
			
		||||
				boolean match = true;
 | 
			
		||||
				for (int j = 1; j < START_SKIP[i].length(); j++) {
 | 
			
		||||
					if (!(statement[position + j] == START_SKIP[i].charAt(j))) {
 | 
			
		||||
						match = false;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (match) {
 | 
			
		||||
					int offset = START_SKIP[i].length();
 | 
			
		||||
					for (int m = position + offset; m < statement.length; m++) {
 | 
			
		||||
						if (statement[m] == STOP_SKIP[i].charAt(0)) {
 | 
			
		||||
							boolean endMatch = true;
 | 
			
		||||
							int endPos = m;
 | 
			
		||||
							for (int n = 1; n < STOP_SKIP[i].length(); n++) {
 | 
			
		||||
								if (m + n >= statement.length) {
 | 
			
		||||
									// last comment not closed properly
 | 
			
		||||
									return statement.length;
 | 
			
		||||
								}
 | 
			
		||||
								if (!(statement[m + n] == STOP_SKIP[i].charAt(n))) {
 | 
			
		||||
									endMatch = false;
 | 
			
		||||
									break;
 | 
			
		||||
								}
 | 
			
		||||
								endPos = m + n;
 | 
			
		||||
							}
 | 
			
		||||
							if (endMatch) {
 | 
			
		||||
								// found character sequence ending comment or quote
 | 
			
		||||
								return endPos + 1;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					// character sequence ending comment or quote not found
 | 
			
		||||
					return statement.length;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return position;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Parse the SQL statement and locate any placeholders or named parameters.
 | 
			
		||||
	 * Named parameters are substituted for a JDBC placeholder and any select list
 | 
			
		||||
	 * is expanded to the required number of placeholders.  Select lists may contain
 | 
			
		||||
	 * an array of objects and in that case the placeholders will be grouped and
 | 
			
		||||
	 * enclosed with parantheses.  This allows for the use of "expression lists" in
 | 
			
		||||
	 * the SQL statement like:<br/>
 | 
			
		||||
	 * 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
 | 
			
		||||
	 * placeholder to be used for a select list. Select lists should be limited
 | 
			
		||||
	 * to 100 or fewer elements. A larger number of elements is not guaramteed to
 | 
			
		||||
	 * be supported by the database and is strictly vendor-dependent.
 | 
			
		||||
	 * @param parsedSql the parsed represenation of the SQL statement
 | 
			
		||||
	 * @param paramSource the source for named parameters
 | 
			
		||||
	 * @return the SQL statement with substituted parameters
 | 
			
		||||
	 * @see #parseSqlStatement
 | 
			
		||||
	 */
 | 
			
		||||
	public static String substituteNamedParameters(ParsedSql parsedSql, SqlParameterSource paramSource) {
 | 
			
		||||
		String originalSql = parsedSql.getOriginalSql();
 | 
			
		||||
		StringBuffer actualSql = new StringBuffer();
 | 
			
		||||
		List paramNames = parsedSql.getParameterNames();
 | 
			
		||||
		int lastIndex = 0;
 | 
			
		||||
		for (int i = 0; i < paramNames.size(); i++) {
 | 
			
		||||
			String paramName = (String) paramNames.get(i);
 | 
			
		||||
			int[] indexes = parsedSql.getParameterIndexes(i);
 | 
			
		||||
			int startIndex = indexes[0];
 | 
			
		||||
			int endIndex = indexes[1];
 | 
			
		||||
			actualSql.append(originalSql.substring(lastIndex, startIndex));
 | 
			
		||||
			if (paramSource != null && paramSource.hasValue(paramName)) {
 | 
			
		||||
				Object value = paramSource.getValue(paramName);
 | 
			
		||||
				if (value instanceof Collection) {
 | 
			
		||||
					Iterator entryIter = ((Collection) value).iterator();
 | 
			
		||||
					int k = 0;
 | 
			
		||||
					while (entryIter.hasNext()) {
 | 
			
		||||
						if (k > 0) {
 | 
			
		||||
							actualSql.append(", ");
 | 
			
		||||
						}
 | 
			
		||||
						k++;
 | 
			
		||||
						Object entryItem = entryIter.next();
 | 
			
		||||
						if (entryItem instanceof Object[]) {
 | 
			
		||||
							Object[] expressionList = (Object[]) entryItem;
 | 
			
		||||
							actualSql.append("(");
 | 
			
		||||
							for (int m = 0; m < expressionList.length; m++) {
 | 
			
		||||
								if (m > 0) {
 | 
			
		||||
									actualSql.append(", ");
 | 
			
		||||
								}
 | 
			
		||||
								actualSql.append("?");
 | 
			
		||||
							}
 | 
			
		||||
							actualSql.append(")");
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
							actualSql.append("?");
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					actualSql.append("?");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				actualSql.append("?");
 | 
			
		||||
			}
 | 
			
		||||
			lastIndex = endIndex;
 | 
			
		||||
		}
 | 
			
		||||
		actualSql.append(originalSql.substring(lastIndex, originalSql.length()));
 | 
			
		||||
		return actualSql.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert a Map of named parameter values to a corresponding array.
 | 
			
		||||
	 * @param parsedSql the parsed SQL statement
 | 
			
		||||
	 * @param paramSource the source for named parameters
 | 
			
		||||
	 * @param declaredParams the List of declared SqlParameter objects
 | 
			
		||||
	 * (may be <code>null</code>). If specified, the parameter metadata will
 | 
			
		||||
	 * be built into the value array in the form of SqlParameterValue objects.
 | 
			
		||||
	 * @return the array of values
 | 
			
		||||
	 */
 | 
			
		||||
	public static Object[] buildValueArray(ParsedSql parsedSql, SqlParameterSource paramSource, List declaredParams) {
 | 
			
		||||
		Object[] paramArray = new Object[parsedSql.getTotalParameterCount()];
 | 
			
		||||
		if (parsedSql.getNamedParameterCount() > 0 && parsedSql.getUnnamedParameterCount() > 0) {
 | 
			
		||||
			throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
					"You can't mix named and traditional ? placeholders. You have " +
 | 
			
		||||
					parsedSql.getNamedParameterCount() + " named parameter(s) and " +
 | 
			
		||||
					parsedSql.getUnnamedParameterCount() + " traditonal placeholder(s) in [" +
 | 
			
		||||
					parsedSql.getOriginalSql() + "]");
 | 
			
		||||
		}
 | 
			
		||||
		List paramNames = parsedSql.getParameterNames();
 | 
			
		||||
		for (int i = 0; i < paramNames.size(); i++) {
 | 
			
		||||
			String paramName = (String) paramNames.get(i);
 | 
			
		||||
			try {
 | 
			
		||||
				Object value = paramSource.getValue(paramName);
 | 
			
		||||
				SqlParameter param = findParameter(declaredParams, paramName, i);
 | 
			
		||||
				paramArray[i] = (param != null ? new SqlParameterValue(param, value) : value);
 | 
			
		||||
			}
 | 
			
		||||
			catch (IllegalArgumentException ex) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
						"No value supplied for the SQL parameter '" + paramName + "': " + ex.getMessage());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return paramArray;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Find a matching parameter in the given list of declared parameters.
 | 
			
		||||
	 * @param declaredParams the declared SqlParameter objects
 | 
			
		||||
	 * @param paramName the name of the desired parameter
 | 
			
		||||
	 * @param paramIndex the index of the desired parameter
 | 
			
		||||
	 * @return the declared SqlParameter, or <code>null</code> if none found
 | 
			
		||||
	 */
 | 
			
		||||
	private static SqlParameter findParameter(List declaredParams, String paramName, int paramIndex) {
 | 
			
		||||
		if (declaredParams != null) {
 | 
			
		||||
			// First pass: Look for named parameter match.
 | 
			
		||||
			for (Iterator it = declaredParams.iterator(); it.hasNext();) {
 | 
			
		||||
				SqlParameter declaredParam = (SqlParameter) it.next();
 | 
			
		||||
				if (paramName.equals(declaredParam.getName())) {
 | 
			
		||||
					return declaredParam;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// Second pass: Look for parameter index match.
 | 
			
		||||
			if (paramIndex < declaredParams.size()) {
 | 
			
		||||
				SqlParameter declaredParam = (SqlParameter) declaredParams.get(paramIndex);
 | 
			
		||||
				// Only accept unnamed parameters for index matches.
 | 
			
		||||
				if (declaredParam.getName() == null) {
 | 
			
		||||
					return declaredParam;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Determine whether a parameter name ends at the current position,
 | 
			
		||||
	 * that is, whether the given character qualifies as a separator.
 | 
			
		||||
	 */
 | 
			
		||||
	private static boolean isParameterSeparator(char c) {
 | 
			
		||||
		if (Character.isWhitespace(c)) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		for (int i = 0; i < PARAMETER_SEPARATORS.length; i++) {
 | 
			
		||||
			if (c == PARAMETER_SEPARATORS[i]) {
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert a Map of parameter types to 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.
 | 
			
		||||
	 * @param parsedSql the parsed SQL statement
 | 
			
		||||
	 * @param paramSource the source for named parameters
 | 
			
		||||
	 */
 | 
			
		||||
	public static int[] buildSqlTypeArray(ParsedSql parsedSql, SqlParameterSource paramSource) {
 | 
			
		||||
		int[] sqlTypes = new int[parsedSql.getTotalParameterCount()];
 | 
			
		||||
		List paramNames = parsedSql.getParameterNames();
 | 
			
		||||
		for (int i = 0; i < paramNames.size(); i++) {
 | 
			
		||||
			String paramName = (String) paramNames.get(i);
 | 
			
		||||
			sqlTypes[i] = paramSource.getSqlType(paramName);
 | 
			
		||||
		}
 | 
			
		||||
		return sqlTypes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Convenience methods operating on a plain SQL String
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Parse the SQL statement and locate any placeholders or named parameters.
 | 
			
		||||
	 * Named parameters are substituted for a JDBC placeholder.
 | 
			
		||||
	 * <p>This is a shortcut version of
 | 
			
		||||
	 * {@link #parseSqlStatement(String)} in combination with
 | 
			
		||||
	 * {@link #substituteNamedParameters(ParsedSql, SqlParameterSource)}.
 | 
			
		||||
	 * @param sql the SQL statement
 | 
			
		||||
	 * @return the actual (parsed) SQL statement
 | 
			
		||||
	 */
 | 
			
		||||
	public static String parseSqlStatementIntoString(String sql) {
 | 
			
		||||
		ParsedSql parsedSql = parseSqlStatement(sql);
 | 
			
		||||
		return substituteNamedParameters(parsedSql, null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Parse the SQL statement and locate any placeholders or named parameters.
 | 
			
		||||
	 * Named parameters are substituted for a JDBC placeholder and any select list
 | 
			
		||||
	 * is expanded to the required number of placeholders.
 | 
			
		||||
	 * <p>This is a shortcut version of
 | 
			
		||||
	 * {@link #substituteNamedParameters(ParsedSql, SqlParameterSource)}.
 | 
			
		||||
	 * @param sql the SQL statement
 | 
			
		||||
	 * @param paramSource the source for named parameters
 | 
			
		||||
	 * @return the SQL statement with substituted parameters
 | 
			
		||||
	 */
 | 
			
		||||
	public static String substituteNamedParameters(String sql, SqlParameterSource paramSource) {
 | 
			
		||||
		ParsedSql parsedSql = parseSqlStatement(sql);
 | 
			
		||||
		return substituteNamedParameters(parsedSql, paramSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convert a Map of named parameter values to a corresponding array.
 | 
			
		||||
	 * <p>This is a shortcut version of
 | 
			
		||||
	 * {@link #buildValueArray(ParsedSql, SqlParameterSource, java.util.List)}.
 | 
			
		||||
	 * @param sql the SQL statement
 | 
			
		||||
	 * @param paramMap the Map of parameters
 | 
			
		||||
	 * @return the array of values
 | 
			
		||||
	 */
 | 
			
		||||
	public static Object[] buildValueArray(String sql, Map paramMap) {
 | 
			
		||||
		ParsedSql parsedSql = parseSqlStatement(sql);
 | 
			
		||||
		return buildValueArray(parsedSql, new MapSqlParameterSource(paramMap), null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,144 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Holds information about a parsed SQL statement.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 */
 | 
			
		||||
public class ParsedSql {
 | 
			
		||||
 | 
			
		||||
	private String originalSql;
 | 
			
		||||
 | 
			
		||||
	private List parameterNames = new ArrayList();
 | 
			
		||||
 | 
			
		||||
	private List parameterIndexes = new ArrayList();
 | 
			
		||||
 | 
			
		||||
	private int namedParameterCount;
 | 
			
		||||
 | 
			
		||||
	private int unnamedParameterCount;
 | 
			
		||||
 | 
			
		||||
	private int totalParameterCount;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new instance of the {@link ParsedSql} class.
 | 
			
		||||
	 * @param originalSql the SQL statement that is being (or is to be) parsed
 | 
			
		||||
	 */
 | 
			
		||||
	ParsedSql(String originalSql) {
 | 
			
		||||
		this.originalSql = originalSql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQL statement that is being parsed.
 | 
			
		||||
	 */
 | 
			
		||||
	String getOriginalSql() {
 | 
			
		||||
		return this.originalSql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a named parameter parsed from this SQL statement.
 | 
			
		||||
	 * @param parameterName the name of the parameter
 | 
			
		||||
	 * @param startIndex the start index in the original SQL String
 | 
			
		||||
	 * @param endIndex the end index in the original SQL String
 | 
			
		||||
	 */
 | 
			
		||||
	void addNamedParameter(String parameterName, int startIndex, int endIndex) {
 | 
			
		||||
		this.parameterNames.add(parameterName);
 | 
			
		||||
		this.parameterIndexes.add(new int[] {startIndex, endIndex});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return all of the parameters (bind variables) in the parsed SQL statement.
 | 
			
		||||
	 * Repeated occurences of the same parameter name are included here.
 | 
			
		||||
	 */
 | 
			
		||||
	List getParameterNames() {
 | 
			
		||||
		return this.parameterNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the parameter indexes for the specified parameter.
 | 
			
		||||
	 * @param parameterPosition the position of the parameter
 | 
			
		||||
	 * (as index in the parameter names List)
 | 
			
		||||
	 * @return the start index and end index, combined into
 | 
			
		||||
	 * a int array of length 2
 | 
			
		||||
	 */
 | 
			
		||||
	int[] getParameterIndexes(int parameterPosition) {
 | 
			
		||||
		return (int[]) this.parameterIndexes.get(parameterPosition);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the count of named parameters in the SQL statement.
 | 
			
		||||
	 * Each parameter name counts once; repeated occurences do not count here.
 | 
			
		||||
	 */
 | 
			
		||||
	void setNamedParameterCount(int namedParameterCount) {
 | 
			
		||||
		this.namedParameterCount = namedParameterCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the count of named parameters in the SQL statement.
 | 
			
		||||
	 * Each parameter name counts once; repeated occurences do not count here.
 | 
			
		||||
	 */
 | 
			
		||||
	int getNamedParameterCount() {
 | 
			
		||||
		return this.namedParameterCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the count of all of the unnamed parameters in the SQL statement.
 | 
			
		||||
	 */
 | 
			
		||||
	void setUnnamedParameterCount(int unnamedParameterCount) {
 | 
			
		||||
		this.unnamedParameterCount = unnamedParameterCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the count of all of the unnamed parameters in the SQL statement.
 | 
			
		||||
	 */
 | 
			
		||||
	int getUnnamedParameterCount() {
 | 
			
		||||
		return this.unnamedParameterCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the total count of all of the parameters in the SQL statement.
 | 
			
		||||
	 * Repeated occurences of the same parameter name do count here.
 | 
			
		||||
	 */
 | 
			
		||||
	void setTotalParameterCount(int totalParameterCount) {
 | 
			
		||||
		this.totalParameterCount = totalParameterCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the total count of all of the parameters in the SQL statement.
 | 
			
		||||
	 * Repeated occurences of the same parameter name do count here.
 | 
			
		||||
	 */
 | 
			
		||||
	int getTotalParameterCount() {
 | 
			
		||||
		return this.totalParameterCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Exposes the original SQL String.
 | 
			
		||||
	 */
 | 
			
		||||
	public String toString() {
 | 
			
		||||
		return this.originalSql;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface that defines common functionality for objects that can
 | 
			
		||||
 * offer parameter values for named SQL parameters, serving as argument
 | 
			
		||||
 * for {@link NamedParameterJdbcTemplate} operations.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This interface allows for the specification of SQL type in addition
 | 
			
		||||
 * to parameter values. All parameter values and types are identified by
 | 
			
		||||
 * specifying the name of the parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Intended to wrap various implementations like a Map or a JavaBean
 | 
			
		||||
 * with a consistent interface.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see NamedParameterJdbcOperations
 | 
			
		||||
 * @see NamedParameterJdbcTemplate
 | 
			
		||||
 * @see MapSqlParameterSource
 | 
			
		||||
 * @see BeanPropertySqlParameterSource
 | 
			
		||||
 */
 | 
			
		||||
public interface SqlParameterSource {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constant that indicates an unknown (or unspecified) SQL type.
 | 
			
		||||
	 * To be returned from <code>getType</code> when no specific SQL type known.
 | 
			
		||||
	 * @see #getSqlType
 | 
			
		||||
	 * @see java.sql.Types
 | 
			
		||||
	 */
 | 
			
		||||
	int TYPE_UNKNOWN = JdbcUtils.TYPE_UNKNOWN;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Determine whether there is a value for the specified named parameter.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @return whether there is a value defined
 | 
			
		||||
	 */
 | 
			
		||||
	boolean hasValue(String paramName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the parameter value for the requested named parameter.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @return the value of the specified parameter
 | 
			
		||||
	 * @throws IllegalArgumentException if there is no value for the requested parameter
 | 
			
		||||
	 */
 | 
			
		||||
	Object getValue(String paramName) throws IllegalArgumentException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Determine the SQL type for the specified named parameter.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @return the SQL type of the specified parameter,
 | 
			
		||||
	 * or <code>TYPE_UNKNOWN</code> if not known
 | 
			
		||||
	 * @see #TYPE_UNKNOWN
 | 
			
		||||
	 */
 | 
			
		||||
	int getSqlType(String paramName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Determine the type ane for the specified named parameter.
 | 
			
		||||
	 * @param paramName the name of the parameter
 | 
			
		||||
	 * @return the type name of the specified parameter,
 | 
			
		||||
	 * or <code>null</code> if not known
 | 
			
		||||
	 */
 | 
			
		||||
	String getTypeName(String paramName);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.namedparam;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameterValue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class that provides helper methods for the use of {@link SqlParameterSource}
 | 
			
		||||
 * with <code>SimpleJdbc</code> classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 * @see org.springframework.jdbc.core.simple.SimpleJdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class SqlParameterSourceUtils {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create an array of MapSqlParameterSource objects populated with data from the
 | 
			
		||||
	 * values passed in. This will define what is included in a batch operation.
 | 
			
		||||
	 * @param valueMaps array of Maps containing the values to be used
 | 
			
		||||
	 * @return an array of SqlParameterSource
 | 
			
		||||
	 */
 | 
			
		||||
	public static SqlParameterSource[] createBatch(Map[] valueMaps) {
 | 
			
		||||
		MapSqlParameterSource[] batch = new MapSqlParameterSource[valueMaps.length];
 | 
			
		||||
		for (int i = 0; i < valueMaps.length; i++) {
 | 
			
		||||
			Map valueMap = valueMaps[i];
 | 
			
		||||
			batch[i] = new MapSqlParameterSource(valueMap);
 | 
			
		||||
		}
 | 
			
		||||
		return batch;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create an array of BeanPropertySqlParameterSource objects populated with data
 | 
			
		||||
	 * from the values passed in. This will define what is included in a batch operation.
 | 
			
		||||
	 * @param beans object array of beans containing the values to be used
 | 
			
		||||
	 * @return an array of SqlParameterSource
 | 
			
		||||
	 */
 | 
			
		||||
	public static SqlParameterSource[] createBatch(Object[] beans) {
 | 
			
		||||
		BeanPropertySqlParameterSource[] batch = new BeanPropertySqlParameterSource[beans.length];
 | 
			
		||||
		for (int i = 0; i < beans.length; i++) {
 | 
			
		||||
			Object bean = beans[i];
 | 
			
		||||
			batch[i] = new BeanPropertySqlParameterSource(bean);
 | 
			
		||||
		}
 | 
			
		||||
		return batch;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a wrapped value if parameter has type information, plain object if not.
 | 
			
		||||
	 * @param source the source of paramer values and type information
 | 
			
		||||
	 * @param parameterName the name of the parameter
 | 
			
		||||
	 * @return the value object
 | 
			
		||||
	 */
 | 
			
		||||
	public static Object getTypedValue(SqlParameterSource source, String parameterName) {
 | 
			
		||||
		int sqlType = source.getSqlType(parameterName);
 | 
			
		||||
		if (sqlType != SqlParameterSource.TYPE_UNKNOWN) {
 | 
			
		||||
			if (source.getTypeName(parameterName) != null) {
 | 
			
		||||
				return new SqlParameterValue(sqlType, source.getTypeName(parameterName), source.getValue(parameterName));
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				return new SqlParameterValue(sqlType, source.getValue(parameterName));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return source.getValue(parameterName);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a Map of case insensitive parameter names together with the original name.
 | 
			
		||||
 * @param parameterSource the source of paramer names
 | 
			
		||||
 * @return the Map that can be used for case insensitive matching of parameter names
 | 
			
		||||
 */
 | 
			
		||||
	public static Map extractCaseInsensitiveParameterNames(SqlParameterSource parameterSource) {
 | 
			
		||||
		Map caseInsensitiveParameterNames = new HashMap();
 | 
			
		||||
		if (parameterSource instanceof BeanPropertySqlParameterSource) {
 | 
			
		||||
			String[] propertyNames = ((BeanPropertySqlParameterSource)parameterSource).getReadablePropertyNames();
 | 
			
		||||
			for (int i = 0; i < propertyNames.length; i++) {
 | 
			
		||||
				String name = propertyNames[i];
 | 
			
		||||
				caseInsensitiveParameterNames.put(name.toLowerCase(), name);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (parameterSource instanceof MapSqlParameterSource) {
 | 
			
		||||
			for (Iterator it = ((MapSqlParameterSource) parameterSource).getValues().keySet().iterator(); it.hasNext();)
 | 
			
		||||
			{
 | 
			
		||||
				String name = (String) it.next();
 | 
			
		||||
				caseInsensitiveParameterNames.put(name.toLowerCase(), name);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return caseInsensitiveParameterNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
<html>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
JdbcTemplate variant with named parameter support.
 | 
			
		||||
 | 
			
		||||
<p>NamedParameterJdbcTemplate is a wrapper around JdbcTemplate that adds
 | 
			
		||||
support for named parameter parsing. It does not implement the JdbcOperations
 | 
			
		||||
interface or extend JdbcTemplate, but implements the dedicated
 | 
			
		||||
NamedParameterJdbcOperations interface.
 | 
			
		||||
 | 
			
		||||
<P>If you need the full power of Spring JDBC for less common operations, use
 | 
			
		||||
the <code>getJdbcOperations()</code> method of NamedParameterJdbcTemplate and
 | 
			
		||||
work with the returned classic template, or use a JdbcTemplate instance directly.
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
<html>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
Provides the core JDBC framework, based on JdbcTemplate
 | 
			
		||||
and its associated callback interfaces and helper objects.
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,407 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.jdbc.core.CallableStatementCreator;
 | 
			
		||||
import org.springframework.jdbc.core.CallableStatementCreatorFactory;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.metadata.CallMetaDataContext;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract class to provide base functionality for easy stored procedure calls
 | 
			
		||||
 * based on configuration options and database metadata.
 | 
			
		||||
 * This class provides the base SPI for {@link SimpleJdbcCall}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractJdbcCall {
 | 
			
		||||
 | 
			
		||||
	/** Logger available to subclasses */
 | 
			
		||||
	protected final Log logger = LogFactory.getLog(getClass());
 | 
			
		||||
 | 
			
		||||
	/** Lower-level class used to execute SQL */
 | 
			
		||||
	private JdbcTemplate jdbcTemplate = new JdbcTemplate();
 | 
			
		||||
 | 
			
		||||
	/** List of SqlParameter objects */
 | 
			
		||||
	private final List<SqlParameter> declaredParameters = new ArrayList<SqlParameter>();
 | 
			
		||||
 | 
			
		||||
	/** List of RefCursor/ResultSet RowMapper objects */
 | 
			
		||||
	private final Map<String, ParameterizedRowMapper> declaredRowMappers = new LinkedHashMap<String, ParameterizedRowMapper>();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Has this operation been compiled? Compilation means at
 | 
			
		||||
	 * least checking that a DataSource and sql have been provided,
 | 
			
		||||
	 * but subclasses may also implement their own custom validation.
 | 
			
		||||
	 */
 | 
			
		||||
	private boolean compiled = false;
 | 
			
		||||
 | 
			
		||||
	/** the generated string used for call statement */
 | 
			
		||||
	private String callString;
 | 
			
		||||
 | 
			
		||||
	/** context used to retrieve and manage database metadata */
 | 
			
		||||
	private CallMetaDataContext callMetaDataContext = new CallMetaDataContext();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Object enabling us to create CallableStatementCreators
 | 
			
		||||
	 * efficiently, based on this class's declared parameters.
 | 
			
		||||
	 */
 | 
			
		||||
	private CallableStatementCreatorFactory callableStatementFactory;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor to be used when initializing using a {@link DataSource}.
 | 
			
		||||
	 * @param dataSource the DataSource to be used
 | 
			
		||||
	 */
 | 
			
		||||
	protected AbstractJdbcCall(DataSource dataSource) {
 | 
			
		||||
		this.jdbcTemplate = new JdbcTemplate(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor to be used when initializing using a {@link JdbcTemplate}.
 | 
			
		||||
	 * @param jdbcTemplate the JdbcTemplate to use
 | 
			
		||||
	 */
 | 
			
		||||
	protected AbstractJdbcCall(JdbcTemplate jdbcTemplate) {
 | 
			
		||||
		this.jdbcTemplate = jdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the configured {@link JdbcTemplate}
 | 
			
		||||
	 */
 | 
			
		||||
	public JdbcTemplate getJdbcTemplate() {
 | 
			
		||||
		return this.jdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the {@link CallableStatementCreatorFactory} being used
 | 
			
		||||
	 */
 | 
			
		||||
	protected CallableStatementCreatorFactory getCallableStatementFactory() {
 | 
			
		||||
		return this.callableStatementFactory;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the name of the stored procedure.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setProcedureName(String procedureName) {
 | 
			
		||||
		this.callMetaDataContext.setProcedureName(procedureName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the stored procedure.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getProcedureName() {
 | 
			
		||||
		return this.callMetaDataContext.getProcedureName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the names of in parameters to be used.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setInParameterNames(Set<String> inParameterNames) {
 | 
			
		||||
		this.callMetaDataContext.setLimitedInParameterNames(inParameterNames);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the names of in parameters to be used.
 | 
			
		||||
	 */
 | 
			
		||||
	public Set<String> getInParameterNames() {
 | 
			
		||||
		return this.callMetaDataContext.getLimitedInParameterNames();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the catalog name to use.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setCatalogName(String catalogName) {
 | 
			
		||||
		this.callMetaDataContext.setCatalogName(catalogName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the catalog name used.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getCatalogName() {
 | 
			
		||||
		return this.callMetaDataContext.getCatalogName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the schema name to use,
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSchemaName(String schemaName) {
 | 
			
		||||
		this.callMetaDataContext.setSchemaName(schemaName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the schema name used.
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSchemaName() {
 | 
			
		||||
		return this.callMetaDataContext.getSchemaName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether this call is a function call.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setFunction(boolean function) {
 | 
			
		||||
		this.callMetaDataContext.setFunction(function);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Is this call a function call?
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isFunction() {
 | 
			
		||||
		return this.callMetaDataContext.isFunction();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether the call requires a rerurn value.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setReturnValueRequired(boolean b) {
 | 
			
		||||
		this.callMetaDataContext.setReturnValueRequired(b);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Does the call require a return value?
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isReturnValueRequired() {
 | 
			
		||||
		return this.callMetaDataContext.isReturnValueRequired();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a declared parameter to the list of parameters for the call.
 | 
			
		||||
	 * Only parameters declared as <code>SqlParameter</code> and <code>SqlInOutParameter</code>
 | 
			
		||||
	 * will be used to provide input values.  This is different from the <code>StoredProcedure</code> class
 | 
			
		||||
	 * which for backwards compatibility reasons allows input values to be provided for parameters declared
 | 
			
		||||
	 * as <code>SqlOutParameter</code>.
 | 
			
		||||
	 * @param parameter the {@link SqlParameter} to add
 | 
			
		||||
	 */
 | 
			
		||||
	public void addDeclaredParameter(SqlParameter parameter) {
 | 
			
		||||
		if (!StringUtils.hasText(parameter.getName())) {
 | 
			
		||||
			throw new InvalidDataAccessApiUsageException("You must specify a parameter name when declaring parameters for \"" + getProcedureName() + "\"");
 | 
			
		||||
		}
 | 
			
		||||
		this.declaredParameters.add(parameter);
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Added declared parameter for [" + getProcedureName() + "]: " + parameter.getName());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a {@link org.springframework.jdbc.core.RowMapper} for the specified parameter or column
 | 
			
		||||
	 * @param parameterName name of parameter or column
 | 
			
		||||
	 * @param rowMapper the RowMapper implementation to use
 | 
			
		||||
	 */
 | 
			
		||||
	public void addDeclaredRowMapper(String parameterName, ParameterizedRowMapper rowMapper) {
 | 
			
		||||
		this.declaredRowMappers.put(parameterName, rowMapper);
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Added row mapper for [" + getProcedureName() + "]: " + parameterName);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the call string that should be used based on parameters and meta data
 | 
			
		||||
	 */
 | 
			
		||||
	public String getCallString() {
 | 
			
		||||
		return this.callString;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify whether the parameter metadata for the call should be used.  The default is true.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setAccessCallParameterMetaData(boolean accessCallParameterMetaData) {
 | 
			
		||||
		this.callMetaDataContext.setAccessCallParameterMetaData(accessCallParameterMetaData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods handling compilation issues
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Compile this JdbcCall using provided parameters and meta data plus other settings.  This
 | 
			
		||||
	 * finalizes the configuration for this object and subsequent attempts to compile are ignored.
 | 
			
		||||
	 * This will be implicitly called the first time an un-compiled call is executed.
 | 
			
		||||
	 * @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't
 | 
			
		||||
	 * been correctly initialized, for example if no DataSource has been provided
 | 
			
		||||
	 */
 | 
			
		||||
	public final void compile() throws InvalidDataAccessApiUsageException {
 | 
			
		||||
		if (!isCompiled()) {
 | 
			
		||||
			if (getProcedureName() == null) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException("Procedure or Function name is required");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			try {
 | 
			
		||||
				this.jdbcTemplate.afterPropertiesSet();
 | 
			
		||||
			}
 | 
			
		||||
			catch (IllegalArgumentException ex) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException(ex.getMessage());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			compileInternal();
 | 
			
		||||
			this.compiled = true;
 | 
			
		||||
 | 
			
		||||
			if (logger.isDebugEnabled()) {
 | 
			
		||||
				logger.debug("SqlCall for " + (isFunction() ? "function" : "procedure") + " [" + getProcedureName() + "] compiled");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to perform the actual compilation.  Subclasses can override this template method to perform
 | 
			
		||||
	 * their own compilation.  Invoked after this base class's compilation is complete.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void compileInternal() {
 | 
			
		||||
		this.callMetaDataContext.initializeMetaData(getJdbcTemplate().getDataSource());
 | 
			
		||||
 | 
			
		||||
		// iterate over the declared RowMappers and register the corresponding SqlParameter
 | 
			
		||||
		for (Map.Entry<String, ParameterizedRowMapper> entry : this.declaredRowMappers.entrySet()) {
 | 
			
		||||
			SqlParameter resultSetParameter =
 | 
			
		||||
					this.callMetaDataContext.createReturnResultSetParameter(entry.getKey(), entry.getValue());
 | 
			
		||||
			this.declaredParameters.add(resultSetParameter);
 | 
			
		||||
		}
 | 
			
		||||
		callMetaDataContext.processParameters(this.declaredParameters);
 | 
			
		||||
 | 
			
		||||
		this.callString = this.callMetaDataContext.createCallString();
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Compiled stored procedure. Call string is [" + this.callString + "]");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.callableStatementFactory =
 | 
			
		||||
				new CallableStatementCreatorFactory(getCallString(), this.callMetaDataContext.getCallParameters());
 | 
			
		||||
		this.callableStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor());
 | 
			
		||||
 | 
			
		||||
		onCompileInternal();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Hook method that subclasses may override to react to compilation.
 | 
			
		||||
	 * This implementation does nothing.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void onCompileInternal() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Is this operation "compiled"?
 | 
			
		||||
	 * @return whether this operation is compiled, and ready to use.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isCompiled() {
 | 
			
		||||
		return this.compiled;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether this operation has been compiled already;
 | 
			
		||||
	 * lazily compile it if not already compiled.
 | 
			
		||||
	 * <p>Automatically called by <code>doExecute</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void checkCompiled() {
 | 
			
		||||
		if (!isCompiled()) {
 | 
			
		||||
			logger.debug("JdbcCall call not compiled before execution - invoking compile");
 | 
			
		||||
			compile();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods handling execution
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the call using the passed in {@link SqlParameterSource}
 | 
			
		||||
	 * @param parameterSource parameter names and values to be used in call
 | 
			
		||||
	 * @return Map of out parameters
 | 
			
		||||
	 */
 | 
			
		||||
	protected Map<String, Object> doExecute(SqlParameterSource parameterSource) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		Map params = matchInParameterValuesWithCallParameters(parameterSource);
 | 
			
		||||
		return executeCallInternal(params);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the call using the passed in Map of parameters
 | 
			
		||||
	 * @param args Map of parameter name and values
 | 
			
		||||
	 * @return Map of out parameters
 | 
			
		||||
	 */
 | 
			
		||||
	protected Map<String, Object> doExecute(Map<String, Object> args) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		Map params = matchInParameterValuesWithCallParameters(args);
 | 
			
		||||
		return executeCallInternal(params);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to perform the actual call processing
 | 
			
		||||
	 */
 | 
			
		||||
	private Map<String, Object> executeCallInternal(Map params) {
 | 
			
		||||
		CallableStatementCreator csc = getCallableStatementFactory().newCallableStatementCreator(params);
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("The following parameters are used for call " + getCallString() + " with: " + params);
 | 
			
		||||
			int i = 1;
 | 
			
		||||
			for (SqlParameter p : getCallParameters()) {
 | 
			
		||||
				logger.debug(i++ + ": " +  p.getName() + " SQL Type "+ p.getSqlType() + " Type Name " + p.getTypeName() + " " + p.getClass().getName());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return getJdbcTemplate().call(csc, getCallParameters());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of a single out parameter or return value.
 | 
			
		||||
	 * Used for functions or procedures with one out parameter.
 | 
			
		||||
	 */
 | 
			
		||||
	protected String getScalarOutParameterName() {
 | 
			
		||||
		return this.callMetaDataContext.getScalarOutParameterName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match the provided in parameter values with registered parameters and
 | 
			
		||||
	 * parameters defined via metadata processing.
 | 
			
		||||
	 * @param parameterSource the parameter vakues provided as a {@link SqlParameterSource}
 | 
			
		||||
	 * @return Map with parameter names and values
 | 
			
		||||
	 */
 | 
			
		||||
	protected Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) {
 | 
			
		||||
		return this.callMetaDataContext.matchInParameterValuesWithCallParameters(parameterSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match the provided in parameter values with registered parameters and
 | 
			
		||||
	 * parameters defined via metadata processing.
 | 
			
		||||
	 * @param args the parameter values provided in a Map
 | 
			
		||||
	 * @return Map with parameter names and values
 | 
			
		||||
	 */
 | 
			
		||||
	protected Map<String, Object> matchInParameterValuesWithCallParameters(Map<String, Object> args) {
 | 
			
		||||
		return this.callMetaDataContext.matchInParameterValuesWithCallParameters(args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get a List of all the call parameters to be used for call. This includes any parameters added
 | 
			
		||||
	 * based on meta data processing.
 | 
			
		||||
	 */
 | 
			
		||||
	protected List<SqlParameter> getCallParameters() {
 | 
			
		||||
		return this.callMetaDataContext.getCallParameters();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,625 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Statement;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
 | 
			
		||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
 | 
			
		||||
import org.springframework.dao.DataIntegrityViolationException;
 | 
			
		||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
 | 
			
		||||
import org.springframework.jdbc.core.ConnectionCallback;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.core.PreparedStatementCreator;
 | 
			
		||||
import org.springframework.jdbc.core.SqlTypeValue;
 | 
			
		||||
import org.springframework.jdbc.core.StatementCreatorUtils;
 | 
			
		||||
import org.springframework.jdbc.core.metadata.TableMetaDataContext;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
 | 
			
		||||
import org.springframework.jdbc.support.JdbcUtils;
 | 
			
		||||
import org.springframework.jdbc.support.KeyHolder;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract class to provide base functionality for easy inserts
 | 
			
		||||
 * based on configuration options and database metadata.
 | 
			
		||||
 * This class provides the base SPI for {@link SimpleJdbcInsert}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractJdbcInsert {
 | 
			
		||||
 | 
			
		||||
	/** Logger available to subclasses */
 | 
			
		||||
	protected final Log logger = LogFactory.getLog(getClass());
 | 
			
		||||
 | 
			
		||||
	/** Lower-level class used to execute SQL */
 | 
			
		||||
	private JdbcTemplate jdbcTemplate = new JdbcTemplate();
 | 
			
		||||
 | 
			
		||||
	/** List of columns objects to be used in insert statement */
 | 
			
		||||
	private List<String> declaredColumns = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Has this operation been compiled? Compilation means at
 | 
			
		||||
	 * least checking that a DataSource or JdbcTemplate has been provided,
 | 
			
		||||
	 * but subclasses may also implement their own custom validation.
 | 
			
		||||
	 */
 | 
			
		||||
	private boolean compiled = false;
 | 
			
		||||
 | 
			
		||||
	/** the generated string used for insert statement */
 | 
			
		||||
	private String insertString;
 | 
			
		||||
 | 
			
		||||
	/** the SQL Type information for the insert columns */
 | 
			
		||||
	private int[] insertTypes;
 | 
			
		||||
 | 
			
		||||
	/** the names of the columns holding the generated key */
 | 
			
		||||
	private String[] generatedKeyNames = new String[] {};
 | 
			
		||||
 | 
			
		||||
	/** context used to retrieve and manage database metadata */
 | 
			
		||||
	private TableMetaDataContext tableMetaDataContext = new TableMetaDataContext();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for sublasses to delegate to for setting the DataSource.
 | 
			
		||||
	 */
 | 
			
		||||
	protected AbstractJdbcInsert(DataSource dataSource) {
 | 
			
		||||
		jdbcTemplate = new JdbcTemplate(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for sublasses to delegate to for setting the JdbcTemplate.
 | 
			
		||||
	 */
 | 
			
		||||
	protected AbstractJdbcInsert(JdbcTemplate jdbcTemplate) {
 | 
			
		||||
		this.jdbcTemplate = jdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods dealing with configuaration properties
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the table for this insert
 | 
			
		||||
	 */
 | 
			
		||||
	public String getTableName() {
 | 
			
		||||
		return tableMetaDataContext.getTableName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the name of the table for this insert
 | 
			
		||||
	 */
 | 
			
		||||
	public void setTableName(String tableName) {
 | 
			
		||||
		checkIfConfigurationModificationIsAllowed();
 | 
			
		||||
		tableMetaDataContext.setTableName(tableName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the schema for this insert
 | 
			
		||||
	 */
 | 
			
		||||
	public String getSchemaName() {
 | 
			
		||||
		return tableMetaDataContext.getSchemaName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the name of the schema for this insert
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSchemaName(String schemaName) {
 | 
			
		||||
		checkIfConfigurationModificationIsAllowed();
 | 
			
		||||
		tableMetaDataContext.setSchemaName(schemaName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the name of the catalog for this insert
 | 
			
		||||
	 */
 | 
			
		||||
	public String getCatalogName() {
 | 
			
		||||
		return tableMetaDataContext.getCatalogName();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the name of the catalog for this insert
 | 
			
		||||
	 */
 | 
			
		||||
	public void setCatalogName(String catalogName) {
 | 
			
		||||
		checkIfConfigurationModificationIsAllowed();
 | 
			
		||||
		tableMetaDataContext.setCatalogName(catalogName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the names of the columns to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public void setColumnNames(List<String> columnNames) {
 | 
			
		||||
		checkIfConfigurationModificationIsAllowed();
 | 
			
		||||
		declaredColumns.clear();
 | 
			
		||||
		declaredColumns.addAll(columnNames);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the names of the columns used
 | 
			
		||||
	 */
 | 
			
		||||
	public List<String> getColumnNames() {
 | 
			
		||||
		return Collections.unmodifiableList(declaredColumns);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the names of any generated keys
 | 
			
		||||
	 */
 | 
			
		||||
	public String[] getGeneratedKeyNames() {
 | 
			
		||||
		return generatedKeyNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the names of any generated keys
 | 
			
		||||
	 */
 | 
			
		||||
	public void setGeneratedKeyNames(String[] generatedKeyNames) {
 | 
			
		||||
		checkIfConfigurationModificationIsAllowed();
 | 
			
		||||
		this.generatedKeyNames = generatedKeyNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the name of a single generated key column
 | 
			
		||||
	 */
 | 
			
		||||
	public void setGeneratedKeyName(String generatedKeyName) {
 | 
			
		||||
		checkIfConfigurationModificationIsAllowed();
 | 
			
		||||
		this.generatedKeyNames = new String[] {generatedKeyName};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the insert string to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public String getInsertString() {
 | 
			
		||||
		return insertString;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the array of {@link java.sql.Types} to be used for insert
 | 
			
		||||
	 */
 | 
			
		||||
	public int[] getInsertTypes() {
 | 
			
		||||
		return insertTypes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get the {@link JdbcTemplate} that is configured to be used
 | 
			
		||||
	 */
 | 
			
		||||
	protected JdbcTemplate getJdbcTemplate() {
 | 
			
		||||
		return jdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods handling compilation issues
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Compile this JdbcInsert using provided parameters and meta data plus other settings.  This
 | 
			
		||||
	 * finalizes the configuration for this object and subsequent attempts to compile are ignored.
 | 
			
		||||
	 * This will be implicitly called the first time an un-compiled insert is executed.
 | 
			
		||||
	 * @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't
 | 
			
		||||
	 * been correctly initialized, for example if no DataSource has been provided
 | 
			
		||||
	 */
 | 
			
		||||
	public final void compile() throws InvalidDataAccessApiUsageException {
 | 
			
		||||
		if (!isCompiled()) {
 | 
			
		||||
			if (getTableName() == null) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException("Table name is required");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			try {
 | 
			
		||||
				this.jdbcTemplate.afterPropertiesSet();
 | 
			
		||||
			}
 | 
			
		||||
			catch (IllegalArgumentException ex) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException(ex.getMessage());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			compileInternal();
 | 
			
		||||
			this.compiled = true;
 | 
			
		||||
 | 
			
		||||
			if (logger.isDebugEnabled()) {
 | 
			
		||||
				logger.debug("JdbcInsert for table [" + getTableName() + "] compiled");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to perform the actual compilation.  Subclasses can override this template method to perform
 | 
			
		||||
	 * their own compilation.  Invoked after this base class's compilation is complete.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void compileInternal() {
 | 
			
		||||
 | 
			
		||||
		tableMetaDataContext.processMetaData(getJdbcTemplate().getDataSource(), getColumnNames(), getGeneratedKeyNames());
 | 
			
		||||
 | 
			
		||||
		insertString = tableMetaDataContext.createInsertString(getGeneratedKeyNames());
 | 
			
		||||
 | 
			
		||||
		insertTypes = tableMetaDataContext.createInsertTypes();
 | 
			
		||||
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Compiled JdbcInsert. Insert string is [" + getInsertString() + "]");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		onCompileInternal();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Hook method that subclasses may override to react to compilation.
 | 
			
		||||
	 * This implementation does nothing.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void onCompileInternal() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Is this operation "compiled"?
 | 
			
		||||
	 * @return whether this operation is compiled, and ready to use.
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isCompiled() {
 | 
			
		||||
		return this.compiled;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check whether this operation has been compiled already;
 | 
			
		||||
	 * lazily compile it if not already compiled.
 | 
			
		||||
	 * <p>Automatically called by <code>validateParameters</code>.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void checkCompiled() {
 | 
			
		||||
		if (!isCompiled()) {
 | 
			
		||||
			logger.debug("JdbcInsert not compiled before execution - invoking compile");
 | 
			
		||||
			compile();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to check whether we are allowd to make any configuration changes at this time.  If the class has been
 | 
			
		||||
	 * compiled, then no further changes to the configuration are allowed.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void checkIfConfigurationModificationIsAllowed() {
 | 
			
		||||
		if (isCompiled()) {
 | 
			
		||||
			throw new InvalidDataAccessApiUsageException("Configuration can't be altered once the class has been compiled or used.");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
	// Methods handling execution
 | 
			
		||||
	//-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the insert using the passed in Map of parameters
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param args Map with parameter names and values to be used in insert
 | 
			
		||||
	 * @return number of rows affected
 | 
			
		||||
	 */
 | 
			
		||||
	protected int doExecute(Map<String, Object> args) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List<Object> values = matchInParameterValuesWithInsertColumns(args);
 | 
			
		||||
		return executeInsertInternal(values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the insert using the passed in {@link SqlParameterSource}
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param parameterSource parameter names and values to be used in insert
 | 
			
		||||
	 * @return number of rows affected
 | 
			
		||||
	 */
 | 
			
		||||
	protected int doExecute(SqlParameterSource parameterSource) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List<Object> values = matchInParameterValuesWithInsertColumns(parameterSource);
 | 
			
		||||
		return executeInsertInternal(values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to execute the insert
 | 
			
		||||
	 */
 | 
			
		||||
	private int executeInsertInternal(List<Object> values) {
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("The following parameters are used for insert " + getInsertString() + " with: " + values);
 | 
			
		||||
		}
 | 
			
		||||
		int updateCount = jdbcTemplate.update(getInsertString(), values.toArray());
 | 
			
		||||
		return updateCount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the insert using the passed in Map of parameters
 | 
			
		||||
	 * and returning a generated key
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param args Map with parameter names and values to be used in insert
 | 
			
		||||
	 * @return the key generated by the insert
 | 
			
		||||
	 */
 | 
			
		||||
	protected Number doExecuteAndReturnKey(Map<String, Object> args) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List<Object> values = matchInParameterValuesWithInsertColumns(args);
 | 
			
		||||
		return executeInsertAndReturnKeyInternal(values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the insert using the passed in {@link SqlParameterSource}
 | 
			
		||||
	 * and returning a generated key
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param parameterSource parameter names and values to be used in insert
 | 
			
		||||
	 * @return the key generated by the insert
 | 
			
		||||
	 */
 | 
			
		||||
	protected Number doExecuteAndReturnKey(SqlParameterSource parameterSource) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List<Object> values = matchInParameterValuesWithInsertColumns(parameterSource);
 | 
			
		||||
		return executeInsertAndReturnKeyInternal(values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the insert using the passed in Map of parameters
 | 
			
		||||
	 * and returning all generated keys
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param args Map with parameter names and values to be used in insert
 | 
			
		||||
	 * @return the KeyHolder containing keys generated by the insert
 | 
			
		||||
	 */
 | 
			
		||||
	protected KeyHolder doExecuteAndReturnKeyHolder(Map<String, Object> args) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List<Object> values = matchInParameterValuesWithInsertColumns(args);
 | 
			
		||||
		return executeInsertAndReturnKeyHolderInternal(values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of the insert using the passed in {@link SqlParameterSource}
 | 
			
		||||
	 * and returning all generated keys
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param parameterSource parameter names and values to be used in insert
 | 
			
		||||
	 * @return the KeyHolder containing keys generated by the insert
 | 
			
		||||
	 */
 | 
			
		||||
	protected KeyHolder doExecuteAndReturnKeyHolder(SqlParameterSource parameterSource) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List<Object> values = matchInParameterValuesWithInsertColumns(parameterSource);
 | 
			
		||||
		return executeInsertAndReturnKeyHolderInternal(values);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to execute the insert generating single key
 | 
			
		||||
	 */
 | 
			
		||||
	private Number executeInsertAndReturnKeyInternal(final List<Object> values) {
 | 
			
		||||
		KeyHolder kh = executeInsertAndReturnKeyHolderInternal(values);
 | 
			
		||||
		if (kh != null && kh.getKey() != null) {
 | 
			
		||||
			return kh.getKey();
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			throw new DataIntegrityViolationException("Unable to retreive the generated key for the insert: " +
 | 
			
		||||
					getInsertString());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to execute the insert generating any number of keys
 | 
			
		||||
	 */
 | 
			
		||||
	private KeyHolder executeInsertAndReturnKeyHolderInternal(final List<Object> values) {
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values);
 | 
			
		||||
		}
 | 
			
		||||
		final KeyHolder keyHolder = new GeneratedKeyHolder();
 | 
			
		||||
		if (this.tableMetaDataContext.isGetGeneratedKeysSupported()) {
 | 
			
		||||
			jdbcTemplate.update(
 | 
			
		||||
					new PreparedStatementCreator() {
 | 
			
		||||
						public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
 | 
			
		||||
							PreparedStatement ps = prepareStatementForGeneratedKeys(con);
 | 
			
		||||
							setParameterValues(ps, values, null);
 | 
			
		||||
							return ps;
 | 
			
		||||
						}
 | 
			
		||||
					},
 | 
			
		||||
					keyHolder);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (!this.tableMetaDataContext.isGetGeneratedKeysSimulated()) {
 | 
			
		||||
				throw new InvalidDataAccessResourceUsageException(
 | 
			
		||||
						"The getGeneratedKeys feature is not supported by this database");
 | 
			
		||||
			}
 | 
			
		||||
			if (getGeneratedKeyNames().length < 1) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException("Generated Key Name(s) not specificed. " +
 | 
			
		||||
						"Using the generated keys features requires specifying the name(s) of the generated column(s)");
 | 
			
		||||
			}
 | 
			
		||||
			if (getGeneratedKeyNames().length > 1) {
 | 
			
		||||
				throw new InvalidDataAccessApiUsageException(
 | 
			
		||||
						"Current database only supports retreiving the key for a single column. There are " +
 | 
			
		||||
						getGeneratedKeyNames().length  + " columns specified: " + Arrays.asList(getGeneratedKeyNames()));
 | 
			
		||||
			}
 | 
			
		||||
			// This is a hack to be able to get the generated key from a database that doesn't support
 | 
			
		||||
			// get generated keys feature.  HSQL is one, PostgreSQL is another.  Postgres uses a RETURNING
 | 
			
		||||
			// clause while HSQL uses a second query that has to be executed with the same connection.
 | 
			
		||||
			final String keyQuery = tableMetaDataContext.getSimulationQueryForGetGeneratedKey(
 | 
			
		||||
					tableMetaDataContext.getTableName(),
 | 
			
		||||
					getGeneratedKeyNames()[0]);
 | 
			
		||||
			Assert.notNull(keyQuery, "Query for simulating get generated keys can't be null");
 | 
			
		||||
			if (keyQuery.toUpperCase().startsWith("RETURNING")) {
 | 
			
		||||
				Long key = jdbcTemplate.queryForLong(
 | 
			
		||||
						getInsertString() + " " + keyQuery,
 | 
			
		||||
						values.toArray(new Object[values.size()]));
 | 
			
		||||
				HashMap keys = new HashMap(1);
 | 
			
		||||
				keys.put(getGeneratedKeyNames()[0], key);
 | 
			
		||||
				keyHolder.getKeyList().add(keys);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				jdbcTemplate.execute(new ConnectionCallback() {
 | 
			
		||||
					public Object doInConnection(Connection con) throws SQLException, DataAccessException {
 | 
			
		||||
						// Do the insert
 | 
			
		||||
						PreparedStatement ps = null;
 | 
			
		||||
						try {
 | 
			
		||||
							ps = con.prepareStatement(getInsertString());
 | 
			
		||||
							setParameterValues(ps, values, null);
 | 
			
		||||
							ps.executeUpdate();
 | 
			
		||||
						} finally {
 | 
			
		||||
							JdbcUtils.closeStatement(ps);
 | 
			
		||||
						}
 | 
			
		||||
						//Get the key
 | 
			
		||||
						Statement keyStmt = null;
 | 
			
		||||
						ResultSet rs = null;
 | 
			
		||||
						HashMap keys = new HashMap(1);
 | 
			
		||||
						try {
 | 
			
		||||
							keyStmt = con.createStatement();
 | 
			
		||||
							rs = keyStmt.executeQuery(keyQuery);
 | 
			
		||||
							if (rs.next()) {
 | 
			
		||||
								long key = rs.getLong(1);
 | 
			
		||||
								keys.put(getGeneratedKeyNames()[0], key);
 | 
			
		||||
								keyHolder.getKeyList().add(keys);
 | 
			
		||||
							}
 | 
			
		||||
						} finally {
 | 
			
		||||
							JdbcUtils.closeResultSet(rs);
 | 
			
		||||
							JdbcUtils.closeStatement(keyStmt);
 | 
			
		||||
						}
 | 
			
		||||
						return null;
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			return keyHolder;
 | 
			
		||||
		}
 | 
			
		||||
		return keyHolder;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create the PreparedStatement to be used for insert that have generated keys
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param con the connection used
 | 
			
		||||
	 * @return PreparedStatement to use
 | 
			
		||||
	 * @throws SQLException
 | 
			
		||||
	 */
 | 
			
		||||
	private PreparedStatement prepareStatementForGeneratedKeys(Connection con) throws SQLException {
 | 
			
		||||
		if (getGeneratedKeyNames().length < 1) {
 | 
			
		||||
			throw new InvalidDataAccessApiUsageException("Generated Key Name(s) not specificed. " +
 | 
			
		||||
					"Using the generated keys features requires specifying the name(s) of the generated column(s)");
 | 
			
		||||
		}
 | 
			
		||||
		PreparedStatement ps;
 | 
			
		||||
		if (this.tableMetaDataContext.isGeneratedKeysColumnNameArraySupported()) {
 | 
			
		||||
			if (logger.isDebugEnabled()) {
 | 
			
		||||
				logger.debug("Using generated keys support with array of column names.");
 | 
			
		||||
			}
 | 
			
		||||
			ps = con.prepareStatement(getInsertString(), getGeneratedKeyNames());
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (logger.isDebugEnabled()) {
 | 
			
		||||
				logger.debug("Using generated keys support with Statement.RETURN_GENERATED_KEYS.");
 | 
			
		||||
			}
 | 
			
		||||
			ps = con.prepareStatement(getInsertString(), Statement.RETURN_GENERATED_KEYS);
 | 
			
		||||
		}
 | 
			
		||||
		return ps;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of a batch insert using the passed in Maps of parameters
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param batch array of Maps with parameter names and values to be used in batch insert
 | 
			
		||||
	 * @return array of number of rows affected
 | 
			
		||||
	 */
 | 
			
		||||
	protected int[] doExecuteBatch(Map<String, Object>[] batch) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List[] batchValues = new ArrayList[batch.length];
 | 
			
		||||
		int i = 0;
 | 
			
		||||
		for (Map<String, Object> args : batch) {
 | 
			
		||||
			List<Object> values = matchInParameterValuesWithInsertColumns(args);
 | 
			
		||||
			batchValues[i++] = values;
 | 
			
		||||
		}
 | 
			
		||||
		return executeBatchInternal(batchValues);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method that provides execution of a batch insert using the passed in array of {@link SqlParameterSource}
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param batch array of SqlParameterSource with parameter names and values to be used in insert
 | 
			
		||||
	 * @return array of number of rows affected
 | 
			
		||||
	 */
 | 
			
		||||
	protected int[] doExecuteBatch(SqlParameterSource[] batch) {
 | 
			
		||||
		checkCompiled();
 | 
			
		||||
		List[] batchValues = new ArrayList[batch.length];
 | 
			
		||||
		int i = 0;
 | 
			
		||||
		for (SqlParameterSource parameterSource : batch) {
 | 
			
		||||
			List<Object> values = matchInParameterValuesWithInsertColumns(parameterSource);
 | 
			
		||||
			batchValues[i++] = values;
 | 
			
		||||
		}
 | 
			
		||||
		return executeBatchInternal(batchValues);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method to execute the batch insert
 | 
			
		||||
	 */
 | 
			
		||||
	//TODO synchronize parameter setters with the SimpleJdbcTemplate
 | 
			
		||||
	private int[] executeBatchInternal(final List<Object>[] batchValues) {
 | 
			
		||||
		if (logger.isDebugEnabled()) {
 | 
			
		||||
			logger.debug("Executing statement " + getInsertString() + " with batch of size: " + batchValues.length);
 | 
			
		||||
		}
 | 
			
		||||
		final int[] columnTypes = getInsertTypes();
 | 
			
		||||
		int[] updateCounts = jdbcTemplate.batchUpdate(
 | 
			
		||||
				getInsertString(),
 | 
			
		||||
				new BatchPreparedStatementSetter() {
 | 
			
		||||
 | 
			
		||||
					public void setValues(PreparedStatement ps, int i) throws SQLException {
 | 
			
		||||
						List<Object> values = batchValues[i];
 | 
			
		||||
						setParameterValues(ps, values, columnTypes);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					public int getBatchSize() {
 | 
			
		||||
						return batchValues.length;
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
		return updateCounts;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Internal implementation for setting parameter values
 | 
			
		||||
	 * @param preparedStatement the PreparedStatement
 | 
			
		||||
	 * @param values the values to be set
 | 
			
		||||
	 */
 | 
			
		||||
	private void setParameterValues(PreparedStatement preparedStatement, List<Object> values, int[] columnTypes)
 | 
			
		||||
			throws SQLException {
 | 
			
		||||
		int colIndex = 0;
 | 
			
		||||
		for (Object value : values) {
 | 
			
		||||
			colIndex++;
 | 
			
		||||
			if (columnTypes == null || colIndex < columnTypes.length) {
 | 
			
		||||
				StatementCreatorUtils.setParameterValue(preparedStatement, colIndex, SqlTypeValue.TYPE_UNKNOWN, value);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				StatementCreatorUtils.setParameterValue(preparedStatement, colIndex, columnTypes[colIndex - 1], value);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match the provided in parameter values with regitered parameters and parameters defined via metedata
 | 
			
		||||
	 * processing.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param parameterSource the parameter vakues provided as a {@link SqlParameterSource}
 | 
			
		||||
	 * @return Map with parameter names and values
 | 
			
		||||
	 */
 | 
			
		||||
	protected List<Object> matchInParameterValuesWithInsertColumns(SqlParameterSource parameterSource) {
 | 
			
		||||
		return tableMetaDataContext.matchInParameterValuesWithInsertColumns(parameterSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Match the provided in parameter values with regitered parameters and parameters defined via metedata
 | 
			
		||||
	 * processing.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param args the parameter values provided in a Map
 | 
			
		||||
	 * @return Map with parameter names and values
 | 
			
		||||
	 */
 | 
			
		||||
	protected List<Object> matchInParameterValuesWithInsertColumns(Map<String, Object> args) {
 | 
			
		||||
		return tableMetaDataContext.matchInParameterValuesWithInsertColumns(args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link ParameterizedRowMapper} implementation that converts a row into a new instance
 | 
			
		||||
 * of the specified mapped target class. The mapped target class must be a top-level class
 | 
			
		||||
 * and it must have a default or no-arg constructor.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Uses Java 5 covariant return types to override the return type of the {@link #mapRow}
 | 
			
		||||
 * method to be the type parameter <code>T</code>.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Column values are mapped based on matching the column name as obtained from result set
 | 
			
		||||
 * metadata to public setters for the corresponding properties. The names are matched either
 | 
			
		||||
 * directly or by transforming a name separating the parts with underscores to the same name
 | 
			
		||||
 * using "camel" case.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Mapping is provided for fields in the target class for many common types, e.g.:
 | 
			
		||||
 * String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long,
 | 
			
		||||
 * float, Float, double, Double, BigDecimal, <code>java.util.Date</code>, etc.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>To facilitate mapping between columns and fields that don't have matching names,
 | 
			
		||||
 * try using column aliases in the SQL statement like "select fname as first_name from customer".
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Please note that this class is designed to provide convenience rather than high performance.
 | 
			
		||||
 * For best performance consider using a custom RowMapper.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 * @see ParameterizedRowMapper
 | 
			
		||||
 */
 | 
			
		||||
public class ParameterizedBeanPropertyRowMapper<T> extends BeanPropertyRowMapper
 | 
			
		||||
		implements ParameterizedRowMapper<T> {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ParameterizedBeanPropertyRowMapper.
 | 
			
		||||
	 * <p>Generally prefer the {@link #newInstance(Class)} method instead,
 | 
			
		||||
	 * which avoids the need for specifying the mapped type twice.
 | 
			
		||||
	 * @see #setMappedClass
 | 
			
		||||
	 */
 | 
			
		||||
	public ParameterizedBeanPropertyRowMapper() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
 | 
			
		||||
		return (T) super.mapRow(rs, rowNumber);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Static factory method to create a new ParameterizedBeanPropertyRowMapper
 | 
			
		||||
	 * (with the mapped class specified only once).
 | 
			
		||||
	 * @param mappedClass the class that each row should be mapped to
 | 
			
		||||
	 */
 | 
			
		||||
	public static <T> ParameterizedBeanPropertyRowMapper<T> newInstance(Class<T> mappedClass) {
 | 
			
		||||
		ParameterizedBeanPropertyRowMapper<T> newInstance = new ParameterizedBeanPropertyRowMapper<T>();
 | 
			
		||||
		newInstance.setMappedClass(mappedClass);
 | 
			
		||||
		return newInstance;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.RowMapper;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of the {@link org.springframework.jdbc.core.RowMapper} interface,
 | 
			
		||||
 * adding type parameterization. Uses Java 5 covariant return types to override
 | 
			
		||||
 * the return type of the {@link #mapRow} method to be the type parameter
 | 
			
		||||
 * <code>T</code>.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rob Harrop
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see org.springframework.jdbc.core.simple.SimpleJdbcOperations
 | 
			
		||||
 */
 | 
			
		||||
public interface ParameterizedRowMapper<T> extends RowMapper {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Implementations should return the object representation of
 | 
			
		||||
	 * the current row in the supplied {@link ResultSet}.
 | 
			
		||||
	 * @see org.springframework.jdbc.core.RowMapper#mapRow
 | 
			
		||||
	 */
 | 
			
		||||
	T mapRow(ResultSet rs, int rowNum) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.SingleColumnRowMapper;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link ParameterizedRowMapper} implementation that converts a single column
 | 
			
		||||
 * into a single result value per row. Expects to operate on a
 | 
			
		||||
 * <code>java.sql.ResultSet</code> that just contains a single column.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The type of the result value for each row can be specified. The value
 | 
			
		||||
 * for the single column will be extracted from the <code>ResultSet</code>
 | 
			
		||||
 * and converted into the specified target type.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Uses Java 5 covariant return types to override the return type of the
 | 
			
		||||
 * {@link #mapRow} method to be the type parameter <code>T</code>.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.5.2
 | 
			
		||||
 */
 | 
			
		||||
public class ParameterizedSingleColumnRowMapper<T> extends SingleColumnRowMapper
 | 
			
		||||
		implements ParameterizedRowMapper<T> {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new ParameterizedSingleColumnRowMapper.
 | 
			
		||||
	 * <p>Generally prefer the {@link #newInstance(Class)} method instead,
 | 
			
		||||
	 * which avoids the need for specifying the mapped type twice.
 | 
			
		||||
	 * @see #setRequiredType
 | 
			
		||||
	 */
 | 
			
		||||
	public ParameterizedSingleColumnRowMapper() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
 | 
			
		||||
		return (T) super.mapRow(rs, rowNumber);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Static factory method to create a new ParameterizedSingleColumnRowMapper
 | 
			
		||||
	 * (with the required type specified only once).
 | 
			
		||||
	 * @param requiredType the type that each result object is expected to match
 | 
			
		||||
	 */
 | 
			
		||||
	public static <T> ParameterizedSingleColumnRowMapper<T> newInstance(Class<T> requiredType) {
 | 
			
		||||
		ParameterizedSingleColumnRowMapper<T> rm = new ParameterizedSingleColumnRowMapper<T>();
 | 
			
		||||
		rm.setRequiredType(requiredType);
 | 
			
		||||
		return rm;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,167 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A SimpleJdbcCall is a multi-threaded, reusable object representing a call
 | 
			
		||||
 * to a stored procedure or a stored function. It provides meta data processing
 | 
			
		||||
 * to simplify the code needed to access basic stored procedures/functions.
 | 
			
		||||
 * All you need to provide is the name of the procedure/function and a Map
 | 
			
		||||
 * containing the parameters when you execute the call. The names of the
 | 
			
		||||
 * supplied parameters will be matched up with in and out parameters declared
 | 
			
		||||
 * when the stored procedure was created.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The meta data processing is based on the DatabaseMetaData provided by
 | 
			
		||||
 * the JDBC driver. Since we rely on the JDBC driver this "auto-detection"
 | 
			
		||||
 * can only be used for databases that are known to provide accurate meta data.
 | 
			
		||||
 * These currently include Derby, MySQL, Microsoft SQL Server, Oracle and DB2.
 | 
			
		||||
 * For any other databases you are required to declare all parameters explicitly.
 | 
			
		||||
 * You can of course declare all parameters explicitly even if the database provides
 | 
			
		||||
 * the necessary meta data. In that case your declared parameters will take precedence.
 | 
			
		||||
 * You can also turn off any mete data processing if you want to use parameter names
 | 
			
		||||
 * that do not match what is declared during the stored procedure compilation.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The actual insert is being handled using Spring's
 | 
			
		||||
 * {@link org.springframework.jdbc.core.JdbcTemplate}.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Many of the configuration methods return the current instance of the SimpleJdbcCall
 | 
			
		||||
 * to provide the ability to string multiple ones together in a "fluid" interface style.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 * @see java.sql.DatabaseMetaData
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOperations {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor that takes one parameter with the JDBC DataSource to use when creating the
 | 
			
		||||
	 * JdbcTemplate.
 | 
			
		||||
	 * @param dataSource the <code>DataSource</code> to use
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcCall(DataSource dataSource) {
 | 
			
		||||
		super(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Alternative Constructor that takes one parameter with the JdbcTemplate to be used.
 | 
			
		||||
	 * @param jdbcTemplate the <code>JdbcTemplate</code> to use
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcCall(JdbcTemplate jdbcTemplate) {
 | 
			
		||||
		super(jdbcTemplate);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall withProcedureName(String procedureName) {
 | 
			
		||||
		setProcedureName(procedureName);
 | 
			
		||||
		setFunction(false);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall withFunctionName(String functionName) {
 | 
			
		||||
		setProcedureName(functionName);
 | 
			
		||||
		setFunction(true);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall withSchemaName(String schemaName) {
 | 
			
		||||
		setSchemaName(schemaName);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall withCatalogName(String catalogName) {
 | 
			
		||||
		setCatalogName(catalogName);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall withReturnValue() {
 | 
			
		||||
		setReturnValueRequired(true);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall declareParameters(SqlParameter... sqlParameters) {
 | 
			
		||||
		for (SqlParameter sqlParameter : sqlParameters) {
 | 
			
		||||
			if (sqlParameter != null) {
 | 
			
		||||
				addDeclaredParameter(sqlParameter);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall useInParameterNames(String... inParameterNames) {
 | 
			
		||||
		setInParameterNames(new HashSet<String>(Arrays.asList(inParameterNames)));
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall returningResultSet(String parameterName, ParameterizedRowMapper rowMapper) {
 | 
			
		||||
		addDeclaredRowMapper(parameterName, rowMapper);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcCall withoutProcedureColumnMetaDataAccess() {
 | 
			
		||||
		setAccessCallParameterMetaData(false);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T executeFunction(Class<T> returnType, Map args) {
 | 
			
		||||
		return (T) doExecute(args).get(getScalarOutParameterName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T executeFunction(Class<T> returnType, MapSqlParameterSource args) {
 | 
			
		||||
		return (T) doExecute(args).get(getScalarOutParameterName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T executeObject(Class<T> returnType, Map args) {
 | 
			
		||||
		return (T) doExecute(args).get(getScalarOutParameterName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T executeObject(Class<T> returnType, MapSqlParameterSource args) {
 | 
			
		||||
		return (T) doExecute(args).get(getScalarOutParameterName());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Map<String, Object> execute() {
 | 
			
		||||
		return doExecute(new HashMap<String, Object>());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Map<String, Object> execute(Map<String, Object> args) {
 | 
			
		||||
		return doExecute(args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Map<String, Object> execute(SqlParameterSource parameterSource) {
 | 
			
		||||
		return doExecute(parameterSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,157 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameter;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface specifying the API for a Simple JDBC Call implemented by {@link SimpleJdbcCall}.
 | 
			
		||||
 * This interface is not often used directly, but provides the
 | 
			
		||||
 * option to enhance testability, as it can easily be mocked or stubbed.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public interface SimpleJdbcCallOperations {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the procedure name to be used - this implies that we will be calling a stored procedure.
 | 
			
		||||
	 * @param procedureName the name of the stored procedure
 | 
			
		||||
	 * @return the instance of this SimpleJdbcCall
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcCallOperations withProcedureName(String procedureName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the procedure name to be used - this implies that we will be calling a stored function.
 | 
			
		||||
	 * @param functionName the name of the stored function
 | 
			
		||||
	 * @return the instance of this SimpleJdbcCall
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcCallOperations withFunctionName(String functionName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Optionally, specify the name of the schema that contins the stored procedure.
 | 
			
		||||
	 * @param schemaName the name of the schema
 | 
			
		||||
	 * @return the instance of this SimpleJdbcCall
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcCallOperations withSchemaName(String schemaName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Optionally, specify the name of the catalog that contins the stored procedure.
 | 
			
		||||
	 * To provide consistency with the Oracle DatabaseMetaData, this is used to specify the package name if
 | 
			
		||||
	 * the procedure is declared as part of a package.
 | 
			
		||||
	 * @param catalogName the catalog or package name
 | 
			
		||||
	 * @return the instance of this SimpleJdbcCall
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcCallOperations withCatalogName(String catalogName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Indicates the procedure's return value should be included in the results returned.
 | 
			
		||||
	 * @return the instance of this SimpleJdbcCall
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcCallOperations withReturnValue();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify one or more parameters if desired.  These parameters will be supplemented with any
 | 
			
		||||
	 * parameter information retrieved from the database meta data.
 | 
			
		||||
	 * Note that only parameters declared as <code>SqlParameter</code> and <code>SqlInOutParameter</code>
 | 
			
		||||
	 * will be used to provide input values.  This is different from the <code>StoredProcedure</code> class
 | 
			
		||||
	 * which for backwards compatibility reasons allows input values to be provided for parameters declared
 | 
			
		||||
	 * as <code>SqlOutParameter</code>.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param sqlParameters the parameters to use
 | 
			
		||||
	 * @return the instance of this SimpleJdbcCall
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcCallOperations declareParameters(SqlParameter... sqlParameters);
 | 
			
		||||
 | 
			
		||||
	/** Not used yet */
 | 
			
		||||
	SimpleJdbcCallOperations useInParameterNames(String... inParameterNames);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Used to specify when a ResultSet is returned by the stored procedure and you want it mapped
 | 
			
		||||
	 * by a RowMapper.  The results will be returned using the parameter name specified.  Multiple
 | 
			
		||||
	 * ResultSets must be declared in the correct order. If the database you are using uses ref cursors
 | 
			
		||||
	 * then the name specified must match the name of the parameter declared for the procedure in the
 | 
			
		||||
	 * database.
 | 
			
		||||
	 * @param parameterName the name of the returned results and/or the name of the ref cursor parameter
 | 
			
		||||
	 * @param rowMapper the RowMapper implementation that will map the data returned for each row
 | 
			
		||||
	 * */
 | 
			
		||||
	SimpleJdbcCallOperations returningResultSet(String parameterName, ParameterizedRowMapper rowMapper);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Turn off any processing of parameter meta data information obtained via JDBC.
 | 
			
		||||
	 * @return the instance of this SimpleJdbcCall
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcCallOperations withoutProcedureColumnMetaDataAccess();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the stored function and return the results obtained as an Object of the specified return type.
 | 
			
		||||
	 * @param returnType the type of the value to return
 | 
			
		||||
	 * @param args Map containing the parameter values to be used in the call.
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T executeFunction(Class<T> returnType, Map args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the stored function and return the results obtained as an Object of the specified return type.
 | 
			
		||||
	 * @param returnType the type of the value to return
 | 
			
		||||
	 * @param args MapSqlParameterSource containing the parameter values to be used in the call.
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T executeFunction(Class<T> returnType, MapSqlParameterSource args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the stored procedure and return the single out parameter as an Object of the specified return type.
 | 
			
		||||
	 * In the case where there are multiple out parameters, the first one is returned and additional out parameters
 | 
			
		||||
	 * are ignored.
 | 
			
		||||
	 * @param returnType the type of the value to return
 | 
			
		||||
	 * @param args Map containing the parameter values to be used in the call.
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T executeObject(Class<T> returnType, Map args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the stored procedure and return the single out parameter as an Object of the specified return type.
 | 
			
		||||
	 * In the case where there are multiple out parameters, the first one is returned and additional out parameters
 | 
			
		||||
	 * are ignored.
 | 
			
		||||
	 * @param returnType the type of the value to return
 | 
			
		||||
	 * @param args MapSqlParameterSource containing the parameter values to be used in the call.
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T executeObject(Class<T> returnType, MapSqlParameterSource args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the stored procedure and return a map of output params, keyed by name as in parameter declarations..
 | 
			
		||||
	 * @return map of output params.
 | 
			
		||||
	 */
 | 
			
		||||
	Map<String, Object> execute();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the stored procedure and return a map of output params, keyed by name as in parameter declarations..
 | 
			
		||||
	 * @param args Map containing the parameter values to be used in the call.
 | 
			
		||||
	 * @return map of output params.
 | 
			
		||||
	 */
 | 
			
		||||
	Map<String, Object> execute(Map<String, Object> args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the stored procedure and return a map of output params, keyed by name as in parameter declarations..
 | 
			
		||||
	 * @param args SqlParameterSource containing the parameter values to be used in the call.
 | 
			
		||||
	 * @return map of output params.
 | 
			
		||||
	 */
 | 
			
		||||
	Map<String, Object> execute(SqlParameterSource args);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.support.JdbcDaoSupport;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of {@link org.springframework.jdbc.core.support.JdbcDaoSupport}
 | 
			
		||||
 * that exposes a {@link #getSimpleJdbcTemplate() SimpleJdbcTemplate} as well.
 | 
			
		||||
 * Only usable on Java 5 and above.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see SimpleJdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class SimpleJdbcDaoSupport extends JdbcDaoSupport {
 | 
			
		||||
	
 | 
			
		||||
	private SimpleJdbcTemplate simpleJdbcTemplate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a SimpleJdbcTemplate based on the configured JdbcTemplate.
 | 
			
		||||
	 */
 | 
			
		||||
	protected void initTemplateConfig() {
 | 
			
		||||
		this.simpleJdbcTemplate = new SimpleJdbcTemplate(getJdbcTemplate());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a SimpleJdbcTemplate wrapping the configured JdbcTemplate.
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcTemplate getSimpleJdbcTemplate() {
 | 
			
		||||
	  return this.simpleJdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,129 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.support.KeyHolder;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A SimpleJdbcInsert is a multi-threaded, reusable object providing easy insert
 | 
			
		||||
 * capabilities for a table. It provides meta data processing to simplify the code
 | 
			
		||||
 * needed to construct a basic insert statement. All you need to provide is the
 | 
			
		||||
 * name of the table and a Map containing the column names and the column values.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The meta data processing is based on the DatabaseMetaData provided by the
 | 
			
		||||
 * JDBC driver.  As long as the JBDC driver can provide the names of the columns
 | 
			
		||||
 * for a specified table than we can rely on this auto-detection feature. If that
 | 
			
		||||
 * is not the case then the column names must be specified explicitly.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The actual insert is being handled using Spring's
 | 
			
		||||
 * {@link org.springframework.jdbc.core.JdbcTemplate}.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Many of the configuration methods return the current instance of the SimpleJdbcInsert
 | 
			
		||||
 * to provide the ability to string multiple ones together in a "fluid" interface style.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 * @see java.sql.DatabaseMetaData
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcInsertOperations {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor that takes one parameter with the JDBC DataSource to use when creating the
 | 
			
		||||
	 * JdbcTemplate.
 | 
			
		||||
	 * @param dataSource the <code>DataSource</code> to use
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcInsert(DataSource dataSource) {
 | 
			
		||||
		super(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Alternative Constructor that takes one parameter with the JdbcTemplate to be used.
 | 
			
		||||
	 * @param jdbcTemplate the <code>JdbcTemplate</code> to use
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcInsert(JdbcTemplate jdbcTemplate) {
 | 
			
		||||
		super(jdbcTemplate);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcInsert withTableName(String tableName) {
 | 
			
		||||
		setTableName(tableName);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcInsert withSchemaName(String schemaName) {
 | 
			
		||||
		setSchemaName(schemaName);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcInsert withCatalogName(String catalogName) {
 | 
			
		||||
		setCatalogName(catalogName);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcInsert usingColumns(String... columnNames) {
 | 
			
		||||
		setColumnNames(Arrays.asList(columnNames));
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public SimpleJdbcInsert usingGeneratedKeyColumns(String... columnNames) {
 | 
			
		||||
		setGeneratedKeyNames(columnNames);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int execute(Map<String, Object> args) {
 | 
			
		||||
		return doExecute(args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int execute(SqlParameterSource parameterSource) {
 | 
			
		||||
		return doExecute(parameterSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Number executeAndReturnKey(Map<String, Object> args) {
 | 
			
		||||
		return doExecuteAndReturnKey(args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public Number executeAndReturnKey(SqlParameterSource parameterSource) {
 | 
			
		||||
		return doExecuteAndReturnKey(parameterSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public KeyHolder executeAndReturnKeyHolder(Map<String, Object> args) {
 | 
			
		||||
		return doExecuteAndReturnKeyHolder(args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public KeyHolder executeAndReturnKeyHolder(SqlParameterSource parameterSource) {
 | 
			
		||||
		return doExecuteAndReturnKeyHolder(parameterSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int[] executeBatch(Map<String, Object>[] batch) {
 | 
			
		||||
		return doExecuteBatch(batch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int[] executeBatch(SqlParameterSource[] batch) {
 | 
			
		||||
		return doExecuteBatch(batch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,134 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.support.KeyHolder;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface specifying the API for a Simple JDBC Insert implemented by {@link SimpleJdbcInsert}.
 | 
			
		||||
 * This interface is not often used directly, but provides the
 | 
			
		||||
 * option to enhance testability, as it can easily be mocked or stubbed.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.5
 | 
			
		||||
 */
 | 
			
		||||
public interface SimpleJdbcInsertOperations {
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the table name to be used for the insert.
 | 
			
		||||
	 * @param tableName the name of the stored table
 | 
			
		||||
	 * @return the instance of this SimpleJdbcInsert
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcInsertOperations withTableName(String tableName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the shema name, if any, to be used for the insert.
 | 
			
		||||
	 * @param schemaName the name of the schema
 | 
			
		||||
	 * @return the instance of this SimpleJdbcInsert
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcInsertOperations withSchemaName(String schemaName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the catalog name, if any, to be used for the insert.
 | 
			
		||||
	 * @param catalogName the name of the catalog
 | 
			
		||||
	 * @return the instance of this SimpleJdbcInsert
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcInsertOperations withCatalogName(String catalogName);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the column names that the insert statement should be limited to use.
 | 
			
		||||
	 * @param columnNames one or more column names
 | 
			
		||||
	 * @return the instance of this SimpleJdbcInsert
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcInsertOperations usingColumns(String... columnNames);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify the name sof any columns that have auto generated keys.
 | 
			
		||||
	 * @param columnNames one or more column names
 | 
			
		||||
	 * @return the instance of this SimpleJdbcInsert
 | 
			
		||||
	 */
 | 
			
		||||
	SimpleJdbcInsertOperations usingGeneratedKeyColumns(String... columnNames);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the insert using the values passed in.
 | 
			
		||||
	 * @param args Map containing column names and corresponding value
 | 
			
		||||
	 * @return the number of rows affected as returned by the JDBC driver
 | 
			
		||||
	 */
 | 
			
		||||
	int execute(Map<String, Object> args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the insert using the values passed in.
 | 
			
		||||
	 * @param parameterSource SqlParameterSource containing values to use for insert
 | 
			
		||||
	 * @return the number of rows affected as returned by the JDBC driver
 | 
			
		||||
	 */
 | 
			
		||||
	int execute(SqlParameterSource parameterSource);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the insert using the values passed in and return the generated key.  This requires that
 | 
			
		||||
	 * the name of the columns with auto generated keys have been specified. This method will always
 | 
			
		||||
	 * return a key or throw an exception if a key was not returned.
 | 
			
		||||
	 * @param args Map containing column names and corresponding value
 | 
			
		||||
	 * @return the generated key value
 | 
			
		||||
	 */
 | 
			
		||||
	Number executeAndReturnKey(Map<String, Object> args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the insert using the values passed in and return the generated key.  This requires that
 | 
			
		||||
	 * the name of the columns with auto generated keys have been specified. This method will always
 | 
			
		||||
	 * return a key or throw an exception if a key was not returned.
 | 
			
		||||
	 * @param parameterSource SqlParameterSource containing values to use for insert
 | 
			
		||||
	 * @return the generated key value.
 | 
			
		||||
	 */
 | 
			
		||||
	Number executeAndReturnKey(SqlParameterSource parameterSource);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the insert using the values passed in and return the generated keys.  This requires that
 | 
			
		||||
	 * the name of the columns with auto generated keys have been specified. This method will always return
 | 
			
		||||
	 * a KeyHolder but the caller must verify that it actually contains the generated keys.
 | 
			
		||||
	 * @param args Map containing column names and corresponding value
 | 
			
		||||
	 * @return the KeyHolder containing all generated keys
 | 
			
		||||
	 */
 | 
			
		||||
	KeyHolder executeAndReturnKeyHolder(Map<String, Object> args);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the insert using the values passed in and return the generated keys.  This requires that
 | 
			
		||||
	 * the name of the columns with auto generated keys have been specified. This method will always return
 | 
			
		||||
	 * a KeyHolder but the caller must verify that it actually contains the generated keys.
 | 
			
		||||
	 * @param parameterSource SqlParameterSource containing values to use for insert
 | 
			
		||||
	 * @return the KeyHolder containing all generated keys
 | 
			
		||||
	 */
 | 
			
		||||
	KeyHolder executeAndReturnKeyHolder(SqlParameterSource parameterSource);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a batch insert using the batch of values passed in.
 | 
			
		||||
	 * @param batch an array of Maps containing a batch of column names and corresponding value
 | 
			
		||||
	 * @return the array of number of rows affected as returned by the JDBC driver
 | 
			
		||||
	 */
 | 
			
		||||
	int[] executeBatch(Map<String, Object>[] batch);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a batch insert using the batch of values passed in.
 | 
			
		||||
	 * @param batch an array of SqlParameterSource containing values for the batch
 | 
			
		||||
	 * @return the array of number of rows affected as returned by the JDBC driver
 | 
			
		||||
	 */
 | 
			
		||||
	int[] executeBatch(SqlParameterSource[] batch);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,386 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcOperations;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * JDBC operations interface usable on Java 5 and above, exposing a
 | 
			
		||||
 * set of common JDBC operations, whose interface is simplified
 | 
			
		||||
 * through the use of varargs and autoboxing.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Rob Harrop
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
 | 
			
		||||
 * @see SimpleJdbcTemplate
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcOperations
 | 
			
		||||
 */
 | 
			
		||||
public interface SimpleJdbcOperations {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Expose the classic Spring JdbcTemplate to allow invocation of less
 | 
			
		||||
	 * commonly used methods.
 | 
			
		||||
	 */
 | 
			
		||||
	JdbcOperations getJdbcOperations();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Expose the Spring NamedParameterJdbcTemplate to allow invocation of less
 | 
			
		||||
	 * commonly used methods.
 | 
			
		||||
	 */
 | 
			
		||||
	NamedParameterJdbcOperations getNamedParameterJdbcOperations();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an <code>int</code> passing in a SQL query
 | 
			
		||||
	 * using the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * and a map containing the arguments.
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql, Map args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an <code>int</code> passing in a SQL query
 | 
			
		||||
	 * using the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * and a <code>SqlParameterSource</code> containing the arguments.
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the query.
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql, SqlParameterSource args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an <code>int</code> passing in a SQL query
 | 
			
		||||
	 * using the standard '?' placeholders for parameters
 | 
			
		||||
	 * and a variable number of arguments.
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 */
 | 
			
		||||
	int queryForInt(String sql, Object... args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an <code>long</code> passing in a SQL query
 | 
			
		||||
	 * using the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * and a map containing the arguments.
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql, Map args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an <code>long</code> passing in a SQL query
 | 
			
		||||
	 * using the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * and a <code>SqlParameterSource</code> containing the arguments.
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the query.
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql, SqlParameterSource args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an <code>long</code> passing in a SQL query
 | 
			
		||||
	 * using the standard '?' placeholders for parameters
 | 
			
		||||
	 * and a variable number of arguments.
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 */
 | 
			
		||||
	long queryForLong(String sql, Object... args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an object of type <code>T</code> identified by the supplied @{@link Class}.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param requiredType the required type of the return value.
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Class)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], Class)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T queryForObject(String sql, Class<T> requiredType, Map args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an object of type <code>T</code> identified by the supplied @{@link Class}.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param requiredType the required type of the return value.
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Class)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], Class)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T queryForObject(String sql, Class<T> requiredType, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an object of type <code>T</code> identified by the supplied @{@link Class}.
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param requiredType the required type of the return value.
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Class)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], Class)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T queryForObject(String sql, Class<T> requiredType, Object... args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an object of type <code>T</code> using the supplied
 | 
			
		||||
	 * {@link ParameterizedRowMapper} to the query results to the object.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param rm the @{@link ParameterizedRowMapper} to use for result mapping
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, Map args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an object of type <code>T</code> using the supplied
 | 
			
		||||
	 * {@link ParameterizedRowMapper} to the query results to the object.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param rm the @{@link ParameterizedRowMapper} to use for result mapping
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for an object of type <code>T</code> using the supplied
 | 
			
		||||
	 * {@link ParameterizedRowMapper} to the query results to the object.
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param rm the @{@link ParameterizedRowMapper} to use for result mapping
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, Object... args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for a {@link List} of <code>Objects</code> of type <code>T</code> using
 | 
			
		||||
	 * the supplied {@link ParameterizedRowMapper} to the query results to the object.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param rm the @{@link ParameterizedRowMapper} to use for result mapping
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> List<T> query(String sql, ParameterizedRowMapper<T> rm, Map args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for a {@link List} of <code>Objects</code> of type <code>T</code> using
 | 
			
		||||
	 * the supplied {@link ParameterizedRowMapper} to the query results to the object.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param rm the @{@link ParameterizedRowMapper} to use for result mapping
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> List<T> query(String sql, ParameterizedRowMapper<T> rm, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query for a {@link List} of <code>Objects</code> of type <code>T</code> using
 | 
			
		||||
	 * the supplied {@link ParameterizedRowMapper} to the query results to the object.
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param rm the @{@link ParameterizedRowMapper} to use for result mapping
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper)
 | 
			
		||||
	 */
 | 
			
		||||
	<T> List<T> query(String sql, ParameterizedRowMapper<T> rm, Object... args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied query with the supplied arguments.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForMap(String)
 | 
			
		||||
	 * @see JdbcOperations#queryForMap(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	Map<String, Object> queryForMap(String sql, Map args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied query with the supplied arguments.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForMap(String)
 | 
			
		||||
	 * @see JdbcOperations#queryForMap(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	Map<String, Object> queryForMap(String sql, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied query with the (optional) supplied arguments.
 | 
			
		||||
	 * <p>The query is expected to be a single row query; the result row will be
 | 
			
		||||
	 * mapped to a Map (one entry for each column, using the column name as the key).
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForMap(String)
 | 
			
		||||
	 * @see JdbcOperations#queryForMap(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	Map<String, Object> queryForMap(String sql, Object... args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied query with the supplied arguments.
 | 
			
		||||
	 * <p>Each element in the returned {@link List} is constructed as a {@link Map}
 | 
			
		||||
	 * as described in {@link #queryForMap}
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForList(String)
 | 
			
		||||
	 * @see JdbcOperations#queryForList(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	List<Map<String, Object>> queryForList(String sql, Map args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied query with the supplied arguments.
 | 
			
		||||
	 * <p>Each element in the returned {@link List} is constructed as a {@link Map}
 | 
			
		||||
	 * as described in {@link #queryForMap}
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForList(String)
 | 
			
		||||
	 * @see JdbcOperations#queryForList(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	List<Map<String, Object>> queryForList(String sql, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied query with the (optional) supplied arguments.
 | 
			
		||||
	 * <p>Each element in the returned {@link List} is constructed as a {@link Map}
 | 
			
		||||
	 * as described in {@link #queryForMap}
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL query to run.
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 * @see JdbcOperations#queryForList(String)
 | 
			
		||||
	 * @see JdbcOperations#queryForList(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	List<Map<String, Object>> queryForList(String sql, Object... args)
 | 
			
		||||
			throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied SQL statement with (optional) supplied arguments.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL statement to execute.
 | 
			
		||||
	 * @param args the map containing the arguments for the query.
 | 
			
		||||
	 * @return the numbers of rows affected by the update.
 | 
			
		||||
	 * @see NamedParameterJdbcOperations#update(String, Map)
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, Map args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied SQL statement with supplied arguments.
 | 
			
		||||
	 * Uses sql with the named parameter support provided by the
 | 
			
		||||
	 * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}
 | 
			
		||||
	 * @param sql the SQL statement to execute.
 | 
			
		||||
	 * @param args the <code>SqlParameterSource</code> containing the arguments for the statement.
 | 
			
		||||
	 * @return the numbers of rows affected by the update.
 | 
			
		||||
	 * @see NamedParameterJdbcOperations#update(String, SqlParameterSource)
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, SqlParameterSource args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the supplied SQL statement with supplied arguments.
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL statement to execute.
 | 
			
		||||
	 * @param args the variable number of arguments for the query.
 | 
			
		||||
	 * @return the numbers of rows affected by the update.
 | 
			
		||||
	 * @see JdbcOperations#update(String)
 | 
			
		||||
	 * @see JdbcOperations#update(String, Object[])
 | 
			
		||||
	 */
 | 
			
		||||
	int update(String sql, Object... args) throws DataAccessException;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Executes a batch using the supplied SQL statement with the batch of supplied arguments.
 | 
			
		||||
	 * Uses sql with the named parameter support.
 | 
			
		||||
	 * @param sql the SQL statement to execute.
 | 
			
		||||
	 * @param batchValues the array of Maps containing the batch of arguments for the query.
 | 
			
		||||
	 * @return an array containing the numbers of rows affected by each update in the batch.
 | 
			
		||||
	 */
 | 
			
		||||
	public int[] batchUpdate(String sql, Map[] batchValues);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a batch using the supplied SQL statement with the batch of supplied arguments.
 | 
			
		||||
	 * Uses sql with the named parameter support.
 | 
			
		||||
	 * @param sql the SQL statement to execute.
 | 
			
		||||
	 * @param batchArgs the array of {@link SqlParameterSource} containing the batch of arguments for the query.
 | 
			
		||||
	 * @return an array containing the numbers of rows affected by each update in the batch.
 | 
			
		||||
	 */
 | 
			
		||||
	public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a batch using the supplied SQL statement with the batch of supplied arguments.
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL statement to execute.
 | 
			
		||||
	 * @param batchArgs the List of Object arrays containing the batch of arguments for the query.
 | 
			
		||||
	 * @return an array containing the numbers of rows affected by each update in the batch.
 | 
			
		||||
	 */
 | 
			
		||||
	public int[] batchUpdate(String sql, List<Object[]> batchArgs);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute a batch using the supplied SQL statement with the batch of supplied arguments.
 | 
			
		||||
	 * Uses sql with the standard '?' placeholders for parameters
 | 
			
		||||
	 * @param sql the SQL statement to execute.
 | 
			
		||||
	 * @param batchArgs the List of Object arrays containing the batch of arguments for the query.
 | 
			
		||||
	 * @param argTypes SQL types of the arguments
 | 
			
		||||
	 * (constants from <code>java.sql.Types</code>)
 | 
			
		||||
	 * @return an array containing the numbers of rows affected by each update in the batch.
 | 
			
		||||
	 */
 | 
			
		||||
	public int[] batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,338 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.simple;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcOperations;
 | 
			
		||||
import org.springframework.jdbc.core.SqlParameterValue;
 | 
			
		||||
import org.springframework.jdbc.core.SqlTypeValue;
 | 
			
		||||
import org.springframework.jdbc.core.StatementCreatorUtils;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.NamedParameterUtils;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.ParsedSql;
 | 
			
		||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
 | 
			
		||||
import org.springframework.util.ObjectUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Java-5-based convenience wrapper for the classic Spring
 | 
			
		||||
 * {@link org.springframework.jdbc.core.JdbcTemplate},
 | 
			
		||||
 * taking advantage of varargs and autoboxing, and exposing only the most
 | 
			
		||||
 * commonly required operations in order to simplify JdbcTemplate usage.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Use the {@link #getJdbcOperations()} method (or a straight JdbcTemplate)
 | 
			
		||||
 * if you need to invoke less commonly used template methods. This includes
 | 
			
		||||
 * any methods specifying SQL types, methods using less commonly used callbacks
 | 
			
		||||
 * such as RowCallbackHandler, updates with PreparedStatementSetters rather than
 | 
			
		||||
 * argument arrays, and stored procedures as well as batch operations.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Rob Harrop
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see ParameterizedRowMapper
 | 
			
		||||
 * @see SimpleJdbcDaoSupport
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public class SimpleJdbcTemplate implements SimpleJdbcOperations {
 | 
			
		||||
	
 | 
			
		||||
	/** The NamedParameterJdbcTemplate that we are wrapping */
 | 
			
		||||
	private final NamedParameterJdbcOperations namedParameterJdbcOperations;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SimpleJdbcTemplate for the given DataSource.
 | 
			
		||||
	 * <p>Creates a classic Spring JdbcTemplate and wraps it.
 | 
			
		||||
	 * @param dataSource the JDBC DataSource to access
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcTemplate(DataSource dataSource) {
 | 
			
		||||
		this.namedParameterJdbcOperations = new NamedParameterJdbcTemplate(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SimpleJdbcTemplate for the given classic Spring JdbcTemplate.
 | 
			
		||||
	 * @param classicJdbcTemplate the classic Spring JdbcTemplate to wrap
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcTemplate(JdbcOperations classicJdbcTemplate) {
 | 
			
		||||
		this.namedParameterJdbcOperations = new NamedParameterJdbcTemplate(classicJdbcTemplate);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new SimpleJdbcTemplate for the given Spring NamedParameterJdbcTemplate.
 | 
			
		||||
	 * @param namedParameterJdbcTemplate the Spring NamedParameterJdbcTemplate to wrap
 | 
			
		||||
	 */
 | 
			
		||||
	public SimpleJdbcTemplate(NamedParameterJdbcOperations namedParameterJdbcTemplate) {
 | 
			
		||||
		this.namedParameterJdbcOperations = namedParameterJdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Expose the classic Spring JdbcTemplate to allow invocation of
 | 
			
		||||
	 * less commonly used methods.
 | 
			
		||||
	 */
 | 
			
		||||
	public JdbcOperations getJdbcOperations() {
 | 
			
		||||
		return this.namedParameterJdbcOperations.getJdbcOperations();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Expose the Spring NamedParameterJdbcTemplate to allow invocation of
 | 
			
		||||
	 * less commonly used methods.
 | 
			
		||||
	 */
 | 
			
		||||
	public NamedParameterJdbcOperations getNamedParameterJdbcOperations() {
 | 
			
		||||
		return this.namedParameterJdbcOperations;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public int queryForInt(String sql, Map args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForInt(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int queryForInt(String sql, SqlParameterSource args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForInt(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int queryForInt(String sql, Object... args) throws DataAccessException {
 | 
			
		||||
		return (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
					getJdbcOperations().queryForInt(sql) :
 | 
			
		||||
					getJdbcOperations().queryForInt(sql, getArguments(args)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public long queryForLong(String sql, Map args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForLong(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public long queryForLong(String sql, SqlParameterSource args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForLong(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public long queryForLong(String sql, Object... args) throws DataAccessException {
 | 
			
		||||
		return (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
					getJdbcOperations().queryForLong(sql) :
 | 
			
		||||
					getJdbcOperations().queryForLong(sql, getArguments(args)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T queryForObject(String sql, Class<T> requiredType, Map args) throws DataAccessException {
 | 
			
		||||
		return (T) getNamedParameterJdbcOperations().queryForObject(sql, args, requiredType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T queryForObject(String sql, Class<T> requiredType, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
		return (T) getNamedParameterJdbcOperations().queryForObject(sql, args, requiredType);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T queryForObject(String sql, Class<T> requiredType, Object... args) throws DataAccessException {
 | 
			
		||||
		return (T) (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
				getJdbcOperations().queryForObject(sql, requiredType) :
 | 
			
		||||
				getJdbcOperations().queryForObject(sql, getArguments(args), requiredType));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, Map args) throws DataAccessException {
 | 
			
		||||
		return (T) getNamedParameterJdbcOperations().queryForObject(sql, args, rm);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
		return (T) getNamedParameterJdbcOperations().queryForObject(sql, args, rm);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, Object... args) throws DataAccessException {
 | 
			
		||||
		return (T) (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
				getJdbcOperations().queryForObject(sql, rm):
 | 
			
		||||
				getJdbcOperations().queryForObject(sql, getArguments(args), rm));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> List<T> query(String sql, ParameterizedRowMapper<T> rm, Map args) throws DataAccessException {
 | 
			
		||||
		return (List<T>) getNamedParameterJdbcOperations().query(sql, args, rm);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> List<T> query(String sql, ParameterizedRowMapper<T> rm, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
		return (List<T>) getNamedParameterJdbcOperations().query(sql, args, rm);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T> List<T> query(String sql, ParameterizedRowMapper<T> rm, Object... args) throws DataAccessException {
 | 
			
		||||
		return (List<T>) (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
				getJdbcOperations().query(sql, rm) :
 | 
			
		||||
				getJdbcOperations().query(sql, getArguments(args), rm));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public Map<String, Object> queryForMap(String sql, Map args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForMap(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public Map<String, Object> queryForMap(String sql, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForMap(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public Map<String, Object> queryForMap(String sql, Object... args) throws DataAccessException {
 | 
			
		||||
		return (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
				getJdbcOperations().queryForMap(sql) :
 | 
			
		||||
				getJdbcOperations().queryForMap(sql, getArguments(args)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public List<Map<String, Object>> queryForList(String sql, Map args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForList(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public List<Map<String, Object>> queryForList(String sql, SqlParameterSource args)
 | 
			
		||||
			throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().queryForList(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public List<Map<String, Object>> queryForList(String sql, Object... args) throws DataAccessException {
 | 
			
		||||
		return (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
				getJdbcOperations().queryForList(sql) :
 | 
			
		||||
				getJdbcOperations().queryForList(sql, getArguments(args)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int update(String sql, Map args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().update(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int update(String sql, SqlParameterSource args) throws DataAccessException {
 | 
			
		||||
		return getNamedParameterJdbcOperations().update(sql, args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int update(String sql, Object ... args) throws DataAccessException {
 | 
			
		||||
		return (ObjectUtils.isEmpty(args) ?
 | 
			
		||||
				getJdbcOperations().update(sql) :
 | 
			
		||||
				getJdbcOperations().update(sql, getArguments(args)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int[] batchUpdate(String sql, List<Object[]> batchArgs) {
 | 
			
		||||
		return doExecuteBatchUpdate(sql, batchArgs, new int[0]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int[] batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes) {
 | 
			
		||||
		return doExecuteBatchUpdate(sql, batchArgs, argTypes);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int[] batchUpdate(String sql, Map[] batchValues) {
 | 
			
		||||
		SqlParameterSource[] batchArgs = new SqlParameterSource[batchValues.length];
 | 
			
		||||
		int i = 0;
 | 
			
		||||
		for (Map values : batchValues) {
 | 
			
		||||
			batchArgs[i] = new MapSqlParameterSource(values);
 | 
			
		||||
			i++;
 | 
			
		||||
		}
 | 
			
		||||
		return doExecuteBatchUpdateWithNamedParameters(sql, batchArgs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs) {
 | 
			
		||||
		return doExecuteBatchUpdateWithNamedParameters(sql, batchArgs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private int[] doExecuteBatchUpdate(String sql, final List<Object[]> batchValues, final int[] columnTypes) {
 | 
			
		||||
		return getJdbcOperations().batchUpdate(
 | 
			
		||||
				sql,
 | 
			
		||||
				new BatchPreparedStatementSetter() {
 | 
			
		||||
 | 
			
		||||
					public void setValues(PreparedStatement ps, int i) throws SQLException {
 | 
			
		||||
						Object[] values = batchValues.get(i);
 | 
			
		||||
						doSetStatementParameters(values, ps, columnTypes);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					public int getBatchSize() {
 | 
			
		||||
						return batchValues.size();
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private int[] doExecuteBatchUpdateWithNamedParameters(String sql, final SqlParameterSource[] batchArgs) {
 | 
			
		||||
		if (batchArgs.length <= 0) {
 | 
			
		||||
			return new int[] {0};
 | 
			
		||||
		}
 | 
			
		||||
		final ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
 | 
			
		||||
		String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, batchArgs[0]);
 | 
			
		||||
		return getJdbcOperations().batchUpdate(
 | 
			
		||||
				sqlToUse,
 | 
			
		||||
				new BatchPreparedStatementSetter() {
 | 
			
		||||
 | 
			
		||||
					public void setValues(PreparedStatement ps, int i) throws SQLException {
 | 
			
		||||
						Object[] values = NamedParameterUtils.buildValueArray(parsedSql, batchArgs[i], null);
 | 
			
		||||
						int[] columnTypes = NamedParameterUtils.buildSqlTypeArray(parsedSql, batchArgs[i]);
 | 
			
		||||
						doSetStatementParameters(values, ps, columnTypes);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					public int getBatchSize() {
 | 
			
		||||
						return batchArgs.length;
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void doSetStatementParameters(Object[] values, PreparedStatement ps, int[] columnTypes) throws SQLException {
 | 
			
		||||
		int colIndex = 0;
 | 
			
		||||
		for (Object value : values) {
 | 
			
		||||
			colIndex++;
 | 
			
		||||
			if (value instanceof SqlParameterValue) {
 | 
			
		||||
				SqlParameterValue paramValue = (SqlParameterValue) value;
 | 
			
		||||
				StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue());
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				int colType;
 | 
			
		||||
				if (columnTypes == null || columnTypes.length < colIndex) {
 | 
			
		||||
					colType = SqlTypeValue.TYPE_UNKNOWN;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					colType = columnTypes[colIndex - 1];
 | 
			
		||||
				}
 | 
			
		||||
				StatementCreatorUtils.setParameterValue(ps, colIndex, colType, value);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Considers an Object array passed into a varargs parameter as
 | 
			
		||||
	 * collection of arguments rather than as single argument.
 | 
			
		||||
	 */
 | 
			
		||||
	private Object[] getArguments(Object[] varArgs) {
 | 
			
		||||
		if (varArgs.length == 1 && varArgs[0] instanceof Object[]) {
 | 
			
		||||
			return (Object[]) varArgs[0];
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			return varArgs;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
<html>
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
Simplification layer over JdbcTemplate for Java 5 and above.
 | 
			
		||||
 | 
			
		||||
<p>SimpleJdbcTemplate is a wrapper around JdbcTemplate that takes advantage
 | 
			
		||||
of varargs and autoboxing. It also offers only a subset of the methods
 | 
			
		||||
available on JdbcTemplate: Hence, it does not implement the JdbcOperations
 | 
			
		||||
interface or extend JdbcTemplate, but implements the dedicated
 | 
			
		||||
SimpleJdbcOperations interface.
 | 
			
		||||
 | 
			
		||||
<P>If you need the full power of Spring JDBC for less common operations,
 | 
			
		||||
use the <code>getJdbcOperations()</code> method of SimpleJdbcTemplate and work
 | 
			
		||||
with the returned classic template, or use a JdbcTemplate instance directly.
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2007 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.support;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.InterruptibleBatchPreparedStatementSetter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract implementation of the {@link InterruptibleBatchPreparedStatementSetter}
 | 
			
		||||
 * interface, combining the check for available values and setting of those
 | 
			
		||||
 * into a single callback method {@link #setValuesIfAvailable}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 2.0
 | 
			
		||||
 * @see #setValuesIfAvailable
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractInterruptibleBatchPreparedStatementSetter
 | 
			
		||||
		implements InterruptibleBatchPreparedStatementSetter {
 | 
			
		||||
 | 
			
		||||
	private boolean exhausted;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This implementation calls {@link #setValuesIfAvailable}
 | 
			
		||||
	 * and sets this instance's exhaustion flag accordingly.
 | 
			
		||||
	 */
 | 
			
		||||
	public final void setValues(PreparedStatement ps, int i) throws SQLException {
 | 
			
		||||
		this.exhausted = !setValuesIfAvailable(ps, i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This implementation return this instance's current exhaustion flag.
 | 
			
		||||
	 */
 | 
			
		||||
	public final boolean isBatchExhausted(int i) {
 | 
			
		||||
		return this.exhausted;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This implementation returns <code>Integer.MAX_VALUE</code>.
 | 
			
		||||
	 * Can be overridden in subclasses to lower the maximum batch size.
 | 
			
		||||
	 */
 | 
			
		||||
	public int getBatchSize() {
 | 
			
		||||
		return Integer.MAX_VALUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Check for available values and set them on the given PreparedStatement.
 | 
			
		||||
	 * If no values are available anymore, return <code>false</code>.
 | 
			
		||||
	 * @param ps PreparedStatement we'll invoke setter methods on
 | 
			
		||||
	 * @param i index of the statement we're issuing in the batch, starting from 0
 | 
			
		||||
	 * @return whether there were values to apply (that is, whether the applied
 | 
			
		||||
	 * parameters should be added to the batch and this method should be called
 | 
			
		||||
	 * for a further iteration)
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered
 | 
			
		||||
	 * (i.e. there is no need to catch SQLException)
 | 
			
		||||
	 */
 | 
			
		||||
	protected abstract boolean setValuesIfAvailable(PreparedStatement ps, int i) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,89 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.support;
 | 
			
		||||
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.jdbc.core.PreparedStatementCallback;
 | 
			
		||||
import org.springframework.jdbc.support.lob.LobCreator;
 | 
			
		||||
import org.springframework.jdbc.support.lob.LobHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract PreparedStatementCallback implementation that manages a LobCreator.
 | 
			
		||||
 * Typically used as inner class, with access to surrounding method arguments.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Delegates to the <code>setValues</code> template method for setting values
 | 
			
		||||
 * on the PreparedStatement, using a given LobCreator for BLOB/CLOB arguments.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A usage example with JdbcTemplate:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 | 
			
		||||
 * LobHandler lobHandler = new DefaultLobHandler();  // reusable object
 | 
			
		||||
 *
 | 
			
		||||
 * jdbcTemplate.execute(
 | 
			
		||||
 *     "INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)",
 | 
			
		||||
 *     new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
 | 
			
		||||
 *       protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
 | 
			
		||||
 *         ps.setString(1, name);
 | 
			
		||||
 *         lobCreator.setBlobAsBinaryStream(ps, 2, contentStream, contentLength);
 | 
			
		||||
 *         lobCreator.setClobAsString(ps, 3, description);
 | 
			
		||||
 *       }
 | 
			
		||||
 *     }
 | 
			
		||||
 * );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.0.2
 | 
			
		||||
 * @see org.springframework.jdbc.support.lob.LobCreator
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractLobCreatingPreparedStatementCallback implements PreparedStatementCallback {
 | 
			
		||||
 | 
			
		||||
	private final LobHandler lobHandler;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new AbstractLobCreatingPreparedStatementCallback for the
 | 
			
		||||
	 * given LobHandler.
 | 
			
		||||
	 * @param lobHandler the LobHandler to create LobCreators with
 | 
			
		||||
	 */
 | 
			
		||||
	public AbstractLobCreatingPreparedStatementCallback(LobHandler lobHandler) {
 | 
			
		||||
		this.lobHandler = lobHandler;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
 | 
			
		||||
		LobCreator lobCreator = this.lobHandler.getLobCreator();
 | 
			
		||||
		try {
 | 
			
		||||
			setValues(ps, lobCreator);
 | 
			
		||||
			return new Integer(ps.executeUpdate());
 | 
			
		||||
		}
 | 
			
		||||
		finally {
 | 
			
		||||
			lobCreator.close();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set values on the given PreparedStatement, using the given
 | 
			
		||||
	 * LobCreator for BLOB/CLOB arguments.
 | 
			
		||||
	 * @param ps the PreparedStatement to use
 | 
			
		||||
	 * @param lobCreator the LobCreator to use
 | 
			
		||||
	 * @throws SQLException if thrown by JDBC methods
 | 
			
		||||
	 * @throws DataAccessException in case of custom exceptions
 | 
			
		||||
	 */
 | 
			
		||||
	protected abstract void setValues(PreparedStatement ps, LobCreator lobCreator)
 | 
			
		||||
			throws SQLException, DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,120 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2005 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.support;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.DataAccessException;
 | 
			
		||||
import org.springframework.dao.EmptyResultDataAccessException;
 | 
			
		||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
 | 
			
		||||
import org.springframework.jdbc.LobRetrievalFailureException;
 | 
			
		||||
import org.springframework.jdbc.core.ResultSetExtractor;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract ResultSetExtractor implementation that assumes streaming of LOB data.
 | 
			
		||||
 * Typically used as inner class, with access to surrounding method arguments.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Delegates to the <code>streamData</code> template method for streaming LOB
 | 
			
		||||
 * content to some OutputStream, typically using a LobHandler. Converts an
 | 
			
		||||
 * IOException thrown during streaming to a LobRetrievalFailureException.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A usage example with JdbcTemplate:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 | 
			
		||||
 * final LobHandler lobHandler = new DefaultLobHandler();  // reusable object
 | 
			
		||||
 *
 | 
			
		||||
 * jdbcTemplate.query(
 | 
			
		||||
 *		 "SELECT content FROM imagedb WHERE image_name=?", new Object[] {name},
 | 
			
		||||
 *		 new AbstractLobStreamingResultSetExtractor() {
 | 
			
		||||
 *			 public void streamData(ResultSet rs) throws SQLException, IOException {
 | 
			
		||||
 *				 FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 1), contentStream);
 | 
			
		||||
 *			 }
 | 
			
		||||
 *		 }
 | 
			
		||||
 * );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.0.2
 | 
			
		||||
 * @see org.springframework.jdbc.support.lob.LobHandler
 | 
			
		||||
 * @see org.springframework.jdbc.LobRetrievalFailureException
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractLobStreamingResultSetExtractor implements ResultSetExtractor {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Delegates to handleNoRowFound, handleMultipleRowsFound and streamData,
 | 
			
		||||
	 * according to the ResultSet state. Converts an IOException thrown by
 | 
			
		||||
	 * streamData to a LobRetrievalFailureException.
 | 
			
		||||
	 * @see #handleNoRowFound
 | 
			
		||||
	 * @see #handleMultipleRowsFound
 | 
			
		||||
	 * @see #streamData
 | 
			
		||||
	 * @see org.springframework.jdbc.LobRetrievalFailureException
 | 
			
		||||
	 */
 | 
			
		||||
	public final Object extractData(ResultSet rs) throws SQLException, DataAccessException {
 | 
			
		||||
		if (!rs.next()) {
 | 
			
		||||
			handleNoRowFound();
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			try {
 | 
			
		||||
				streamData(rs);
 | 
			
		||||
				if (rs.next()) {
 | 
			
		||||
					handleMultipleRowsFound();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch (IOException ex) {
 | 
			
		||||
				throw new LobRetrievalFailureException("Couldn't stream LOB content", ex);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Handle the case where the ResultSet does not contain a row.
 | 
			
		||||
	 * @throws DataAccessException a corresponding exception,
 | 
			
		||||
	 * by default an EmptyResultDataAccessException
 | 
			
		||||
	 * @see org.springframework.dao.EmptyResultDataAccessException
 | 
			
		||||
	 */
 | 
			
		||||
	protected void handleNoRowFound() throws DataAccessException {
 | 
			
		||||
		throw new EmptyResultDataAccessException(
 | 
			
		||||
				"LobStreamingResultSetExtractor did not find row in database", 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Handle the case where the ResultSet contains multiple rows.
 | 
			
		||||
	 * @throws DataAccessException a corresponding exception,
 | 
			
		||||
	 * by default an IncorrectResultSizeDataAccessException
 | 
			
		||||
	 * @see org.springframework.dao.IncorrectResultSizeDataAccessException
 | 
			
		||||
	 */
 | 
			
		||||
	protected void handleMultipleRowsFound() throws DataAccessException {
 | 
			
		||||
		throw new IncorrectResultSizeDataAccessException(
 | 
			
		||||
				"LobStreamingResultSetExtractor found multiple rows in database", 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Stream LOB content from the given ResultSet to some OutputStream.
 | 
			
		||||
	 * <p>Typically used as inner class, with access to surrounding method arguments
 | 
			
		||||
	 * and to a LobHandler instance variable of the surrounding class.
 | 
			
		||||
	 * @param rs the ResultSet to take the LOB content from
 | 
			
		||||
	 * @throws SQLException if thrown by JDBC methods
 | 
			
		||||
	 * @throws IOException if thrown by stream access methods
 | 
			
		||||
	 * @throws DataAccessException in case of custom exceptions
 | 
			
		||||
	 * @see org.springframework.jdbc.support.lob.LobHandler#getBlobAsBinaryStream
 | 
			
		||||
	 * @see org.springframework.util.FileCopyUtils
 | 
			
		||||
	 */
 | 
			
		||||
	protected abstract void streamData(ResultSet rs) throws SQLException, IOException, DataAccessException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.support;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.SqlTypeValue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract implementation of the SqlTypeValue interface, for convenient
 | 
			
		||||
 * creation of type values that are supposed to be passed into the
 | 
			
		||||
 * <code>PreparedStatement.setObject</code> method. The <code>createTypeValue</code>
 | 
			
		||||
 * callback method has access to the underlying Connection, if that should
 | 
			
		||||
 * be needed to create any database-specific objects.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A usage example from a StoredProcedure (compare this to the plain
 | 
			
		||||
 * SqlTypeValue version in the superclass javadoc):
 | 
			
		||||
 *
 | 
			
		||||
 * <pre class="code">proc.declareParameter(new SqlParameter("myarray", Types.ARRAY, "NUMBERS"));
 | 
			
		||||
 * ...
 | 
			
		||||
 *
 | 
			
		||||
 * Map in = new HashMap();
 | 
			
		||||
 * in.put("myarray", new AbstractSqlTypeValue() {
 | 
			
		||||
 *   public Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException {
 | 
			
		||||
 *	   oracle.sql.ArrayDescriptor desc = new oracle.sql.ArrayDescriptor(typeName, con);
 | 
			
		||||
 *	   return new oracle.sql.ARRAY(desc, con, seats);
 | 
			
		||||
 *   }
 | 
			
		||||
 * });
 | 
			
		||||
 * Map out = execute(in);
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see java.sql.PreparedStatement#setObject(int, Object, int)
 | 
			
		||||
 * @see org.springframework.jdbc.object.StoredProcedure
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractSqlTypeValue implements SqlTypeValue {
 | 
			
		||||
 | 
			
		||||
	public final void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
 | 
			
		||||
			throws SQLException {
 | 
			
		||||
 | 
			
		||||
		Object value = createTypeValue(ps.getConnection(), sqlType, typeName);
 | 
			
		||||
		if (sqlType == TYPE_UNKNOWN) {
 | 
			
		||||
			ps.setObject(paramIndex, value);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			ps.setObject(paramIndex, value, sqlType);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create the type value to be passed into <code>PreparedStatement.setObject</code>.
 | 
			
		||||
	 * @param con the JDBC Connection, if needed to create any database-specific objects
 | 
			
		||||
	 * @param sqlType SQL type of the parameter we are setting
 | 
			
		||||
	 * @param typeName the type name of the parameter
 | 
			
		||||
	 * @return the type value
 | 
			
		||||
	 * @throws SQLException if a SQLException is encountered setting
 | 
			
		||||
	 * parameter values (that is, there's no need to catch SQLException)
 | 
			
		||||
	 * @see java.sql.PreparedStatement#setObject(int, Object, int)
 | 
			
		||||
	 */
 | 
			
		||||
	protected abstract Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.support;
 | 
			
		||||
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 | 
			
		||||
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.core.RowCallbackHandler;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Bean definition reader that reads values from a database table,
 | 
			
		||||
 * based on a given SQL statement.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Expects columns for bean name, property name and value as String.
 | 
			
		||||
 * Formats for each are identical to the properties format recognized
 | 
			
		||||
 * by PropertiesBeanDefinitionReader.
 | 
			
		||||
 *
 | 
			
		||||
 * <p><b>NOTE:</b> This is mainly intended as an example for a custom
 | 
			
		||||
 * JDBC-based bean definition reader. It does not aim to offer
 | 
			
		||||
 * comprehensive functionality.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rod Johnson
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @see #loadBeanDefinitions
 | 
			
		||||
 * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
 | 
			
		||||
 */
 | 
			
		||||
public class JdbcBeanDefinitionReader {
 | 
			
		||||
 | 
			
		||||
	private final PropertiesBeanDefinitionReader propReader;
 | 
			
		||||
 | 
			
		||||
	private JdbcTemplate jdbcTemplate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new JdbcBeanDefinitionReader for the given bean factory,
 | 
			
		||||
	 * using a default PropertiesBeanDefinitionReader underneath.
 | 
			
		||||
	 * <p>DataSource or JdbcTemplate still need to be set.
 | 
			
		||||
	 * @see #setDataSource
 | 
			
		||||
	 * @see #setJdbcTemplate
 | 
			
		||||
	 */
 | 
			
		||||
	public JdbcBeanDefinitionReader(BeanDefinitionRegistry beanFactory) {
 | 
			
		||||
		this.propReader = new PropertiesBeanDefinitionReader(beanFactory);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new JdbcBeanDefinitionReader that delegates to the
 | 
			
		||||
	 * given PropertiesBeanDefinitionReader underneath.
 | 
			
		||||
	 * <p>DataSource or JdbcTemplate still need to be set.
 | 
			
		||||
	 * @see #setDataSource
 | 
			
		||||
	 * @see #setJdbcTemplate
 | 
			
		||||
	 */
 | 
			
		||||
	public JdbcBeanDefinitionReader(PropertiesBeanDefinitionReader beanDefinitionReader) {
 | 
			
		||||
		Assert.notNull(beanDefinitionReader, "Bean definition reader must not be null");
 | 
			
		||||
		this.propReader = beanDefinitionReader;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the DataSource to use to obtain database connections.
 | 
			
		||||
	 * Will implicitly create a new JdbcTemplate with the given DataSource.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setDataSource(DataSource dataSource) {
 | 
			
		||||
		this.jdbcTemplate = new JdbcTemplate(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the JdbcTemplate to be used by this bean factory.
 | 
			
		||||
	 * Contains settings for DataSource, SQLExceptionTranslator, NativeJdbcExtractor, etc.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
 | 
			
		||||
		Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null");
 | 
			
		||||
		this.jdbcTemplate = jdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Load bean definitions from the database via the given SQL string.
 | 
			
		||||
	 * @param sql SQL query to use for loading bean definitions.
 | 
			
		||||
	 * The first three columns must be bean name, property name and value.
 | 
			
		||||
	 * Any join and any other columns are permitted: e.g.
 | 
			
		||||
	 * <code>SELECT BEAN_NAME, PROPERTY, VALUE FROM CONFIG WHERE CONFIG.APP_ID = 1</code>
 | 
			
		||||
	 * It's also possible to perform a join. Column names are not significant --
 | 
			
		||||
	 * only the ordering of these first three columns.
 | 
			
		||||
	 */
 | 
			
		||||
	public void loadBeanDefinitions(String sql) {
 | 
			
		||||
		Assert.notNull(this.jdbcTemplate, "Not fully configured - specify DataSource or JdbcTemplate");
 | 
			
		||||
		final Properties props = new Properties();
 | 
			
		||||
		this.jdbcTemplate.query(sql, new RowCallbackHandler() {
 | 
			
		||||
			public void processRow(ResultSet rs) throws SQLException {
 | 
			
		||||
				String beanName = rs.getString(1);
 | 
			
		||||
				String property = rs.getString(2);
 | 
			
		||||
				String value = rs.getString(3);
 | 
			
		||||
				// Make a properties entry by combining bean name and property.
 | 
			
		||||
				props.setProperty(beanName + "." + property, value);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		this.propReader.registerBeanDefinitions(props);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,145 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2008 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.support;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.dao.support.DaoSupport;
 | 
			
		||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
 | 
			
		||||
import org.springframework.jdbc.core.JdbcTemplate;
 | 
			
		||||
import org.springframework.jdbc.datasource.DataSourceUtils;
 | 
			
		||||
import org.springframework.jdbc.support.SQLExceptionTranslator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convenient super class for JDBC-based data access objects.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Requires a {@link javax.sql.DataSource} to be set, providing a
 | 
			
		||||
 * {@link org.springframework.jdbc.core.JdbcTemplate} based on it to
 | 
			
		||||
 * subclasses through the {@link #getJdbcTemplate()} method.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This base class is mainly intended for JdbcTemplate usage but can
 | 
			
		||||
 * also be used when working with a Connection directly or when using
 | 
			
		||||
 * <code>org.springframework.jdbc.object</code> operation objects.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 28.07.2003
 | 
			
		||||
 * @see #setDataSource
 | 
			
		||||
 * @see #getJdbcTemplate
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcTemplate
 | 
			
		||||
 */
 | 
			
		||||
public abstract class JdbcDaoSupport extends DaoSupport {
 | 
			
		||||
 | 
			
		||||
	private JdbcTemplate jdbcTemplate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the JDBC DataSource to be used by this DAO.
 | 
			
		||||
	 */
 | 
			
		||||
	public final void setDataSource(DataSource dataSource) {
 | 
			
		||||
		if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
 | 
			
		||||
			this.jdbcTemplate = createJdbcTemplate(dataSource);
 | 
			
		||||
			initTemplateConfig();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a JdbcTemplate for the given DataSource.
 | 
			
		||||
	 * Only invoked if populating the DAO with a DataSource reference!
 | 
			
		||||
	 * <p>Can be overridden in subclasses to provide a JdbcTemplate instance
 | 
			
		||||
	 * with different configuration, or a custom JdbcTemplate subclass.
 | 
			
		||||
	 * @param dataSource the JDBC DataSource to create a JdbcTemplate for
 | 
			
		||||
	 * @return the new JdbcTemplate instance
 | 
			
		||||
	 * @see #setDataSource
 | 
			
		||||
	 */
 | 
			
		||||
	protected JdbcTemplate createJdbcTemplate(DataSource dataSource) {
 | 
			
		||||
		return new JdbcTemplate(dataSource);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the JDBC DataSource used by this DAO.
 | 
			
		||||
	 */
 | 
			
		||||
	public final DataSource getDataSource() {
 | 
			
		||||
		return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the JdbcTemplate for this DAO explicitly,
 | 
			
		||||
	 * as an alternative to specifying a DataSource.
 | 
			
		||||
	 */
 | 
			
		||||
	public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
 | 
			
		||||
		this.jdbcTemplate = jdbcTemplate;
 | 
			
		||||
		initTemplateConfig();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the JdbcTemplate for this DAO,
 | 
			
		||||
	 * pre-initialized with the DataSource or set explicitly.
 | 
			
		||||
	 */
 | 
			
		||||
	public final JdbcTemplate getJdbcTemplate() {
 | 
			
		||||
	  return this.jdbcTemplate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize the template-based configuration of this DAO.
 | 
			
		||||
	 * Called after a new JdbcTemplate has been set, either directly
 | 
			
		||||
	 * or through a DataSource.
 | 
			
		||||
	 * <p>This implementation is empty. Subclasses may override this
 | 
			
		||||
	 * to configure further objects based on the JdbcTemplate.
 | 
			
		||||
	 * @see #getJdbcTemplate()
 | 
			
		||||
	 */
 | 
			
		||||
	protected void initTemplateConfig() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected void checkDaoConfig() {
 | 
			
		||||
		if (this.jdbcTemplate == null) {
 | 
			
		||||
			throw new IllegalArgumentException("'dataSource' or 'jdbcTemplate' is required");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the SQLExceptionTranslator of this DAO's JdbcTemplate,
 | 
			
		||||
	 * for translating SQLExceptions in custom JDBC access code.
 | 
			
		||||
	 * @see org.springframework.jdbc.core.JdbcTemplate#getExceptionTranslator()
 | 
			
		||||
	 */
 | 
			
		||||
	protected final SQLExceptionTranslator getExceptionTranslator() {
 | 
			
		||||
		return getJdbcTemplate().getExceptionTranslator();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get a JDBC Connection, either from the current transaction or a new one.
 | 
			
		||||
	 * @return the JDBC Connection
 | 
			
		||||
	 * @throws CannotGetJdbcConnectionException if the attempt to get a Connection failed
 | 
			
		||||
	 * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection(javax.sql.DataSource)
 | 
			
		||||
	 */
 | 
			
		||||
	protected final Connection getConnection() throws CannotGetJdbcConnectionException {
 | 
			
		||||
		return DataSourceUtils.getConnection(getDataSource());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Close the given JDBC Connection, created via this DAO's DataSource,
 | 
			
		||||
	 * if it isn't bound to the thread.
 | 
			
		||||
	 * @param con Connection to close
 | 
			
		||||
	 * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection
 | 
			
		||||
	 */
 | 
			
		||||
	protected final void releaseConnection(Connection con) {
 | 
			
		||||
		DataSourceUtils.releaseConnection(con, getDataSource());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,215 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2006 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.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.jdbc.core.support;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.sql.Types;
 | 
			
		||||
 | 
			
		||||
import org.springframework.jdbc.core.DisposableSqlTypeValue;
 | 
			
		||||
import org.springframework.jdbc.support.lob.DefaultLobHandler;
 | 
			
		||||
import org.springframework.jdbc.support.lob.LobCreator;
 | 
			
		||||
import org.springframework.jdbc.support.lob.LobHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Object to represent an SQL BLOB/CLOB value parameter. BLOBs can either be an
 | 
			
		||||
 * InputStream or a byte array. CLOBs can be in the form of a Reader, InputStream
 | 
			
		||||
 * or String. Each CLOB/BLOB value will be stored together with its length.
 | 
			
		||||
 * The type is based on which constructor is used. Objects of this class are
 | 
			
		||||
 * immutable except for the LobCreator reference. Use them and discard them.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This class holds a reference to a LocCreator that must be closed after the
 | 
			
		||||
 * update has completed. This is done via a call to the closeLobCreator method.
 | 
			
		||||
 * All handling of the LobCreator is done by the framework classes that use it -
 | 
			
		||||
 * no need to set or close the LobCreator for end users of this class.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>A usage example:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 | 
			
		||||
 * LobHandler lobHandler = new DefaultLobHandler();  // reusable object
 | 
			
		||||
 *
 | 
			
		||||
 * jdbcTemplate.update(
 | 
			
		||||
 *     "INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)",
 | 
			
		||||
 *     new Object[] {
 | 
			
		||||
 *       name,
 | 
			
		||||
 *       new SqlLobValue(contentStream, contentLength, lobHandler),
 | 
			
		||||
 *       new SqlLobValue(description, lobHandler)
 | 
			
		||||
 *     },
 | 
			
		||||
 *     new int[] {Types.VARCHAR, Types.BLOB, Types.CLOB});
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *   
 | 
			
		||||
 * @author Thomas Risberg
 | 
			
		||||
 * @author Juergen Hoeller
 | 
			
		||||
 * @since 1.1
 | 
			
		||||
 * @see org.springframework.jdbc.support.lob.LobHandler
 | 
			
		||||
 * @see org.springframework.jdbc.support.lob.LobCreator
 | 
			
		||||
 * @see org.springframework.jdbc.core.JdbcTemplate#update(String, Object[], int[])
 | 
			
		||||
 * @see org.springframework.jdbc.object.SqlUpdate#update(Object[])
 | 
			
		||||
 * @see org.springframework.jdbc.object.StoredProcedure#execute(java.util.Map)
 | 
			
		||||
 */
 | 
			
		||||
public class SqlLobValue implements DisposableSqlTypeValue {
 | 
			
		||||
 | 
			
		||||
	private final Object content;
 | 
			
		||||
 | 
			
		||||
	private final int length;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This contains a reference to the LobCreator - so we can close it
 | 
			
		||||
	 * once the update is done.
 | 
			
		||||
	 */
 | 
			
		||||
	private final LobCreator lobCreator;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BLOB value with the given byte array,
 | 
			
		||||
	 * using a DefaultLobHandler.
 | 
			
		||||
	 * @param bytes the byte array containing the BLOB value
 | 
			
		||||
	 * @see org.springframework.jdbc.support.lob.DefaultLobHandler
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(byte[] bytes) {
 | 
			
		||||
		this(bytes, new DefaultLobHandler());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BLOB value with the given byte array.
 | 
			
		||||
	 * @param bytes the byte array containing the BLOB value
 | 
			
		||||
	 * @param lobHandler the LobHandler to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(byte[] bytes, LobHandler lobHandler) {
 | 
			
		||||
		this.content = bytes;
 | 
			
		||||
		this.length = (bytes != null ? bytes.length : 0);
 | 
			
		||||
		this.lobCreator = lobHandler.getLobCreator();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new CLOB value with the given content string,
 | 
			
		||||
	 * using a DefaultLobHandler.
 | 
			
		||||
	 * @param content the String containing the CLOB value
 | 
			
		||||
	 * @see org.springframework.jdbc.support.lob.DefaultLobHandler
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(String content) {
 | 
			
		||||
		this(content, new DefaultLobHandler());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new CLOB value with the given content string.
 | 
			
		||||
	 * @param content the String containing the CLOB value
 | 
			
		||||
	 * @param lobHandler the LobHandler to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(String content, LobHandler lobHandler) {
 | 
			
		||||
		this.content = content;
 | 
			
		||||
		this.length = (content != null ? content.length() : 0);
 | 
			
		||||
		this.lobCreator = lobHandler.getLobCreator();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BLOB/CLOB value with the given stream,
 | 
			
		||||
	 * using a DefaultLobHandler.
 | 
			
		||||
	 * @param stream the stream containing the LOB value
 | 
			
		||||
	 * @param length the length of the LOB value
 | 
			
		||||
	 * @see org.springframework.jdbc.support.lob.DefaultLobHandler
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(InputStream stream, int length) {
 | 
			
		||||
		this(stream, length, new DefaultLobHandler());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new BLOB/CLOB value with the given stream.
 | 
			
		||||
	 * @param stream the stream containing the LOB value
 | 
			
		||||
	 * @param length the length of the LOB value
 | 
			
		||||
	 * @param lobHandler the LobHandler to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(InputStream stream, int length, LobHandler lobHandler) {
 | 
			
		||||
		this.content = stream;
 | 
			
		||||
		this.length = length;
 | 
			
		||||
		this.lobCreator = lobHandler.getLobCreator();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new CLOB value with the given character stream,
 | 
			
		||||
	 * using a DefaultLobHandler.
 | 
			
		||||
	 * @param reader the character stream containing the CLOB value
 | 
			
		||||
	 * @param length the length of the CLOB value
 | 
			
		||||
	 * @see org.springframework.jdbc.support.lob.DefaultLobHandler
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(Reader reader, int length) {
 | 
			
		||||
		this(reader, length, new DefaultLobHandler());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new CLOB value with the given character stream.
 | 
			
		||||
	 * @param reader the character stream containing the CLOB value
 | 
			
		||||
	 * @param length the length of the CLOB value
 | 
			
		||||
	 * @param lobHandler the LobHandler to be used
 | 
			
		||||
	 */
 | 
			
		||||
	public SqlLobValue(Reader reader, int length, LobHandler lobHandler) {
 | 
			
		||||
		this.content = reader;
 | 
			
		||||
		this.length = length;
 | 
			
		||||
		this.lobCreator = lobHandler.getLobCreator();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the specified content via the LobCreator.
 | 
			
		||||
	 */
 | 
			
		||||
	public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
 | 
			
		||||
			throws SQLException {
 | 
			
		||||
		if (sqlType == Types.BLOB) {
 | 
			
		||||
			if (this.content instanceof byte[] || this.content == null) {
 | 
			
		||||
				this.lobCreator.setBlobAsBytes(ps, paramIndex, (byte[]) this.content);
 | 
			
		||||
			}
 | 
			
		||||
			else if (this.content instanceof String) {
 | 
			
		||||
				this.lobCreator.setBlobAsBytes(ps, paramIndex, ((String) this.content).getBytes());
 | 
			
		||||
			}
 | 
			
		||||
			else if (this.content instanceof InputStream) {
 | 
			
		||||
				this.lobCreator.setBlobAsBinaryStream(ps, paramIndex, (InputStream) this.content, this.length);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				throw new IllegalArgumentException(
 | 
			
		||||
						"Content type [" + this.content.getClass().getName() + "] not supported for BLOB columns");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (sqlType == Types.CLOB) {
 | 
			
		||||
			if (this.content instanceof String || this.content == null) {
 | 
			
		||||
				this.lobCreator.setClobAsString(ps, paramIndex, (String) this.content);
 | 
			
		||||
			}
 | 
			
		||||
			else if (this.content instanceof InputStream) {
 | 
			
		||||
				this.lobCreator.setClobAsAsciiStream(ps, paramIndex, (InputStream) this.content, this.length);
 | 
			
		||||
			}
 | 
			
		||||
			else if (this.content instanceof Reader) {
 | 
			
		||||
				this.lobCreator.setClobAsCharacterStream(ps, paramIndex, (Reader) this.content, this.length);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				throw new IllegalArgumentException(
 | 
			
		||||
						"Content type [" + this.content.getClass().getName() + "] not supported for CLOB columns");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			throw new IllegalArgumentException("SqlLobValue only supports SQL types BLOB and CLOB");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Close the LobCreator, if any.
 | 
			
		||||
	 */
 | 
			
		||||
	public void cleanup() {
 | 
			
		||||
		this.lobCreator.close();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue