1 /*
2  * Copyright 2002-2008 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.jdbc.core.namedparam;
18 
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.Map;
22 
23 import org.springframework.jdbc.core.SqlParameterValue;
24 import org.springframework.util.Assert;
25 
26 /**
27  * {@link SqlParameterSource} implementation that holds a given Map of parameters.
28  *
29  * <p>This class is intended for passing in a simple Map of parameter values
30  * to the methods of the {@link NamedParameterJdbcTemplate} class.
31  *
32  * <p>The <code>addValue</code> methods on this class will make adding several
33  * values easier. The methods return a reference to the {@link MapSqlParameterSource}
34  * itself, so you can chain several method calls together within a single statement.
35  *
36  * @author Thomas Risberg
37  * @author Juergen Hoeller
38  * @since 2.0
39  * @see #addValue(String, Object)
40  * @see #addValue(String, Object, int)
41  * @see #registerSqlType
42  * @see NamedParameterJdbcTemplate
43  */
44 public class MapSqlParameterSource extends AbstractSqlParameterSource {
45 
46 	private final Map<String, Object> values = new HashMap<String, Object>();
47 
48 
49 	/**
50 	 * Create an empty MapSqlParameterSource,
51 	 * with values to be added via <code>addValue</code>.
52 	 * @see #addValue(String, Object)
53 	 */
MapSqlParameterSource()54 	public MapSqlParameterSource() {
55 	}
56 
57 	/**
58 	 * Create a new MapSqlParameterSource, with one value
59 	 * comprised of the supplied arguments.
60 	 * @param paramName the name of the parameter
61 	 * @param value the value of the parameter
62 	 * @see #addValue(String, Object)
63 	 */
MapSqlParameterSource(String paramName, Object value)64 	public MapSqlParameterSource(String paramName, Object value) {
65 		addValue(paramName, value);
66 	}
67 
68 	/**
69 	 * Create a new MapSqlParameterSource based on a Map.
70 	 * @param values a Map holding existing parameter values (can be <code>null</code>)
71 	 */
MapSqlParameterSource(Map<String, ?> values)72 	public MapSqlParameterSource(Map<String, ?> values) {
73 		addValues(values);
74 	}
75 
76 
77 	/**
78 	 * Add a parameter to this parameter source.
79 	 * @param paramName the name of the parameter
80 	 * @param value the value of the parameter
81 	 * @return a reference to this parameter source,
82 	 * so it's possible to chain several calls together
83 	 */
addValue(String paramName, Object value)84 	public MapSqlParameterSource addValue(String paramName, Object value) {
85 		Assert.notNull(paramName, "Parameter name must not be null");
86 		this.values.put(paramName, value);
87 		if (value instanceof SqlParameterValue) {
88 			registerSqlType(paramName, ((SqlParameterValue) value).getSqlType());
89 		}
90 		return this;
91 	}
92 
93 	/**
94 	 * Add a parameter to this parameter source.
95 	 * @param paramName the name of the parameter
96 	 * @param value the value of the parameter
97 	 * @param sqlType the SQL type of the parameter
98 	 * @return a reference to this parameter source,
99 	 * so it's possible to chain several calls together
100 	 */
addValue(String paramName, Object value, int sqlType)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 	 */
addValue(String paramName, Object value, int sqlType, String typeName)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</code>)
128 	 * @return a reference to this parameter source,
129 	 * so it's possible to chain several calls together
130 	 */
addValues(Map<String, ?> values)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 	 */
getValues()147 	public Map<String, Object> getValues() {
148 		return Collections.unmodifiableMap(this.values);
149 	}
150 
151 
hasValue(String paramName)152 	public boolean hasValue(String paramName) {
153 		return this.values.containsKey(paramName);
154 	}
155 
getValue(String paramName)156 	public Object getValue(String paramName) {
157 		if (!hasValue(paramName)) {
158 			throw new IllegalArgumentException("No value registered for key '" + paramName + "'");
159 		}
160 		return this.values.get(paramName);
161 	}
162 
163 }
164