001/*
002 * Copyright 2002-2020 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.namedparam;
018
019import java.util.Arrays;
020import java.util.Collection;
021import java.util.HashMap;
022import java.util.Map;
023
024import org.springframework.jdbc.core.SqlParameterValue;
025import org.springframework.lang.Nullable;
026
027/**
028 * Class that provides helper methods for the use of {@link SqlParameterSource},
029 * in particular with {@link NamedParameterJdbcTemplate}.
030 *
031 * @author Thomas Risberg
032 * @author Juergen Hoeller
033 * @since 2.5
034 */
035public abstract class SqlParameterSourceUtils {
036
037        /**
038         * Create an array of {@link SqlParameterSource} objects populated with data
039         * from the values passed in (either a {@link Map} or a bean object).
040         * This will define what is included in a batch operation.
041         * @param candidates object array of objects containing the values to be used
042         * @return an array of {@link SqlParameterSource}
043         * @see MapSqlParameterSource
044         * @see BeanPropertySqlParameterSource
045         * @see NamedParameterJdbcTemplate#batchUpdate(String, SqlParameterSource[])
046         */
047        public static SqlParameterSource[] createBatch(Object... candidates) {
048                return createBatch(Arrays.asList(candidates));
049        }
050
051        /**
052         * Create an array of {@link SqlParameterSource} objects populated with data
053         * from the values passed in (either a {@link Map} or a bean object).
054         * This will define what is included in a batch operation.
055         * @param candidates collection of objects containing the values to be used
056         * @return an array of {@link SqlParameterSource}
057         * @since 5.0.2
058         * @see MapSqlParameterSource
059         * @see BeanPropertySqlParameterSource
060         * @see NamedParameterJdbcTemplate#batchUpdate(String, SqlParameterSource[])
061         */
062        @SuppressWarnings("unchecked")
063        public static SqlParameterSource[] createBatch(Collection<?> candidates) {
064                SqlParameterSource[] batch = new SqlParameterSource[candidates.size()];
065                int i = 0;
066                for (Object candidate : candidates) {
067                        batch[i] = (candidate instanceof Map ? new MapSqlParameterSource((Map<String, ?>) candidate) :
068                                        new BeanPropertySqlParameterSource(candidate));
069                        i++;
070                }
071                return batch;
072        }
073
074        /**
075         * Create an array of {@link MapSqlParameterSource} objects populated with data from
076         * the values passed in. This will define what is included in a batch operation.
077         * @param valueMaps array of {@link Map} instances containing the values to be used
078         * @return an array of {@link SqlParameterSource}
079         * @see MapSqlParameterSource
080         * @see NamedParameterJdbcTemplate#batchUpdate(String, Map[])
081         */
082        public static SqlParameterSource[] createBatch(Map<String, ?>[] valueMaps) {
083                SqlParameterSource[] batch = new SqlParameterSource[valueMaps.length];
084                for (int i = 0; i < valueMaps.length; i++) {
085                        batch[i] = new MapSqlParameterSource(valueMaps[i]);
086                }
087                return batch;
088        }
089
090        /**
091         * Create a wrapped value if parameter has type information, plain object if not.
092         * @param source the source of parameter values and type information
093         * @param parameterName the name of the parameter
094         * @return the value object
095         * @see SqlParameterValue
096         */
097        @Nullable
098        public static Object getTypedValue(SqlParameterSource source, String parameterName) {
099                int sqlType = source.getSqlType(parameterName);
100                if (sqlType != SqlParameterSource.TYPE_UNKNOWN) {
101                        return new SqlParameterValue(sqlType, source.getTypeName(parameterName), source.getValue(parameterName));
102                }
103                else {
104                        return source.getValue(parameterName);
105                }
106        }
107
108        /**
109         * Create a Map of case insensitive parameter names together with the original name.
110         * @param parameterSource the source of parameter names
111         * @return the Map that can be used for case insensitive matching of parameter names
112         */
113        public static Map<String, String> extractCaseInsensitiveParameterNames(SqlParameterSource parameterSource) {
114                Map<String, String> caseInsensitiveParameterNames = new HashMap<>();
115                String[] paramNames = parameterSource.getParameterNames();
116                if (paramNames != null) {
117                        for (String name : paramNames) {
118                                caseInsensitiveParameterNames.put(name.toLowerCase(), name);
119                        }
120                }
121                return caseInsensitiveParameterNames;
122        }
123
124}