001/* 002 * Copyright 2002-2014 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.Collections; 020import java.util.LinkedHashMap; 021import java.util.Map; 022 023import org.springframework.jdbc.core.SqlParameterValue; 024import org.springframework.util.Assert; 025 026/** 027 * {@link SqlParameterSource} implementation that holds a given Map of parameters. 028 * 029 * <p>This class is intended for passing in a simple Map of parameter values 030 * to the methods of the {@link NamedParameterJdbcTemplate} class. 031 * 032 * <p>The {@code addValue} methods on this class will make adding several values 033 * easier. The methods return a reference to the {@link MapSqlParameterSource} 034 * itself, so you can chain several method calls together within a single statement. 035 * 036 * @author Thomas Risberg 037 * @author Juergen Hoeller 038 * @since 2.0 039 * @see #addValue(String, Object) 040 * @see #addValue(String, Object, int) 041 * @see #registerSqlType 042 * @see NamedParameterJdbcTemplate 043 */ 044public class MapSqlParameterSource extends AbstractSqlParameterSource { 045 046 private final Map<String, Object> values = new LinkedHashMap<String, Object>(); 047 048 049 /** 050 * Create an empty MapSqlParameterSource, 051 * with values to be added via {@code addValue}. 052 * @see #addValue(String, Object) 053 */ 054 public MapSqlParameterSource() { 055 } 056 057 /** 058 * Create a new MapSqlParameterSource, with one value 059 * comprised of the supplied arguments. 060 * @param paramName the name of the parameter 061 * @param value the value of the parameter 062 * @see #addValue(String, Object) 063 */ 064 public MapSqlParameterSource(String paramName, Object value) { 065 addValue(paramName, value); 066 } 067 068 /** 069 * Create a new MapSqlParameterSource based on a Map. 070 * @param values a Map holding existing parameter values (can be {@code null}) 071 */ 072 public MapSqlParameterSource(Map<String, ?> values) { 073 addValues(values); 074 } 075 076 077 /** 078 * Add a parameter to this parameter source. 079 * @param paramName the name of the parameter 080 * @param value the value of the parameter 081 * @return a reference to this parameter source, 082 * so it's possible to chain several calls together 083 */ 084 public MapSqlParameterSource addValue(String paramName, Object value) { 085 Assert.notNull(paramName, "Parameter name must not be null"); 086 this.values.put(paramName, value); 087 if (value instanceof SqlParameterValue) { 088 registerSqlType(paramName, ((SqlParameterValue) value).getSqlType()); 089 } 090 return this; 091 } 092 093 /** 094 * Add a parameter to this parameter source. 095 * @param paramName the name of the parameter 096 * @param value the value of the parameter 097 * @param sqlType the SQL type of the parameter 098 * @return a reference to this parameter source, 099 * so it's possible to chain several calls together 100 */ 101 public MapSqlParameterSource addValue(String paramName, Object value, int sqlType) { 102 Assert.notNull(paramName, "Parameter name must not be null"); 103 this.values.put(paramName, value); 104 registerSqlType(paramName, sqlType); 105 return this; 106 } 107 108 /** 109 * Add a parameter to this parameter source. 110 * @param paramName the name of the parameter 111 * @param value the value of the parameter 112 * @param sqlType the SQL type of the parameter 113 * @param typeName the type name of the parameter 114 * @return a reference to this parameter source, 115 * so it's possible to chain several calls together 116 */ 117 public MapSqlParameterSource addValue(String paramName, Object value, int sqlType, String typeName) { 118 Assert.notNull(paramName, "Parameter name must not be null"); 119 this.values.put(paramName, value); 120 registerSqlType(paramName, sqlType); 121 registerTypeName(paramName, typeName); 122 return this; 123 } 124 125 /** 126 * Add a Map of parameters to this parameter source. 127 * @param values a Map holding existing parameter values (can be {@code null}) 128 * @return a reference to this parameter source, 129 * so it's possible to chain several calls together 130 */ 131 public MapSqlParameterSource addValues(Map<String, ?> values) { 132 if (values != null) { 133 for (Map.Entry<String, ?> entry : values.entrySet()) { 134 this.values.put(entry.getKey(), entry.getValue()); 135 if (entry.getValue() instanceof SqlParameterValue) { 136 SqlParameterValue value = (SqlParameterValue) entry.getValue(); 137 registerSqlType(entry.getKey(), value.getSqlType()); 138 } 139 } 140 } 141 return this; 142 } 143 144 /** 145 * Expose the current parameter values as read-only Map. 146 */ 147 public Map<String, Object> getValues() { 148 return Collections.unmodifiableMap(this.values); 149 } 150 151 152 @Override 153 public boolean hasValue(String paramName) { 154 return this.values.containsKey(paramName); 155 } 156 157 @Override 158 public Object getValue(String paramName) { 159 if (!hasValue(paramName)) { 160 throw new IllegalArgumentException("No value registered for key '" + paramName + "'"); 161 } 162 return this.values.get(paramName); 163 } 164 165}