001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.jdbc.core.support;
018
019import java.sql.Connection;
020import java.sql.PreparedStatement;
021import java.sql.SQLException;
022
023import org.springframework.jdbc.core.SqlTypeValue;
024
025/**
026 * Abstract implementation of the SqlTypeValue interface, for convenient
027 * creation of type values that are supposed to be passed into the
028 * {@code PreparedStatement.setObject} method. The {@code createTypeValue}
029 * callback method has access to the underlying Connection, if that should
030 * be needed to create any database-specific objects.
031 *
032 * <p>A usage example from a StoredProcedure (compare this to the plain
033 * SqlTypeValue version in the superclass javadoc):
034 *
035 * <pre class="code">proc.declareParameter(new SqlParameter("myarray", Types.ARRAY, "NUMBERS"));
036 * ...
037 *
038 * Map&lt;String, Object&gt; in = new HashMap&lt;String, Object&gt;();
039 * in.put("myarray", new AbstractSqlTypeValue() {
040 *   public Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException {
041 *         oracle.sql.ArrayDescriptor desc = new oracle.sql.ArrayDescriptor(typeName, con);
042 *         return new oracle.sql.ARRAY(desc, con, seats);
043 *   }
044 * });
045 * Map out = execute(in);
046 * </pre>
047 *
048 * @author Juergen Hoeller
049 * @since 1.1
050 * @see java.sql.PreparedStatement#setObject(int, Object, int)
051 * @see org.springframework.jdbc.object.StoredProcedure
052 */
053public abstract class AbstractSqlTypeValue implements SqlTypeValue {
054
055        @Override
056        public final void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
057                        throws SQLException {
058
059                Object value = createTypeValue(ps.getConnection(), sqlType, typeName);
060                if (sqlType == TYPE_UNKNOWN) {
061                        ps.setObject(paramIndex, value);
062                }
063                else {
064                        ps.setObject(paramIndex, value, sqlType);
065                }
066        }
067
068        /**
069         * Create the type value to be passed into {@code PreparedStatement.setObject}.
070         * @param con the JDBC Connection, if needed to create any database-specific objects
071         * @param sqlType SQL type of the parameter we are setting
072         * @param typeName the type name of the parameter
073         * @return the type value
074         * @throws SQLException if a SQLException is encountered setting
075         * parameter values (that is, there's no need to catch SQLException)
076         * @see java.sql.PreparedStatement#setObject(int, Object, int)
077         */
078        protected abstract Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException;
079
080}