1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.scripting.defaults;
17
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.ArgumentMatchers.anyInt;
20 import static org.mockito.Mockito.doThrow;
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.verify;
23 import static org.mockito.Mockito.when;
24
25 import java.sql.PreparedStatement;
26 import java.sql.SQLException;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30
31 import org.apache.ibatis.builder.StaticSqlSource;
32 import org.apache.ibatis.domain.blog.Author;
33 import org.apache.ibatis.domain.blog.Section;
34 import org.apache.ibatis.mapping.BoundSql;
35 import org.apache.ibatis.mapping.MappedStatement;
36 import org.apache.ibatis.mapping.ParameterMapping;
37 import org.apache.ibatis.mapping.ResultMap;
38 import org.apache.ibatis.mapping.ResultMapping;
39 import org.apache.ibatis.mapping.SqlCommandType;
40 import org.apache.ibatis.reflection.DefaultReflectorFactory;
41 import org.apache.ibatis.reflection.MetaObject;
42 import org.apache.ibatis.reflection.ReflectorFactory;
43 import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
44 import org.apache.ibatis.reflection.factory.ObjectFactory;
45 import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
46 import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
47 import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
48 import org.apache.ibatis.session.Configuration;
49 import org.apache.ibatis.type.JdbcType;
50 import org.apache.ibatis.type.TypeException;
51 import org.apache.ibatis.type.TypeHandler;
52 import org.apache.ibatis.type.TypeHandlerRegistry;
53 import org.junit.jupiter.api.Assertions;
54 import org.junit.jupiter.api.Test;
55
56
57
58
59
60
61 class DefaultParameterHandlerTest {
62
63 @Test
64 void setParametersThrowsProperException() throws SQLException {
65 final MappedStatement mappedStatement = getMappedStatement();
66 final Object parameterObject = null;
67 final BoundSql boundSql = mock(BoundSql.class);
68
69 TypeHandler<Object> typeHandler = mock(TypeHandler.class);
70 doThrow(new SQLException("foo")).when(typeHandler).setParameter(any(PreparedStatement.class), anyInt(), any(),
71 any(JdbcType.class));
72 ParameterMapping parameterMapping = new ParameterMapping.Builder(mappedStatement.getConfiguration(), "prop",
73 typeHandler).build();
74 List<ParameterMapping> parameterMappings = List.of(parameterMapping);
75 when(boundSql.getParameterMappings()).thenReturn(parameterMappings);
76
77 DefaultParameterHandler defaultParameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject,
78 boundSql);
79
80 PreparedStatement ps = mock(PreparedStatement.class);
81 try {
82 defaultParameterHandler.setParameters(ps);
83 Assertions.fail("Should have thrown TypeException");
84 } catch (Exception e) {
85 Assertions.assertTrue(e instanceof TypeException, "expected TypeException");
86 Assertions.assertTrue(e.getMessage().contains("mapping: ParameterMapping"));
87 }
88
89 }
90
91 MappedStatement getMappedStatement() {
92 final Configuration config = new Configuration();
93 final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
94 return new MappedStatement.Builder(config, "testSelect", new StaticSqlSource(config, "some select statement"),
95 SqlCommandType.SELECT).resultMaps(new ArrayList<ResultMap>() {
96 private static final long serialVersionUID = 1L;
97
98 {
99 add(new ResultMap.Builder(config, "testMap", HashMap.class, new ArrayList<ResultMapping>() {
100 private static final long serialVersionUID = 1L;
101
102 {
103 add(new ResultMapping.Builder(config, "cOlUmN1", "CoLuMn1", registry.getTypeHandler(Integer.class))
104 .build());
105 }
106 }).build());
107 }
108 }).build();
109 }
110
111 @Test
112 void parameterObjectGetPropertyValueWithAdditionalParameter() throws SQLException {
113 Configuration config = new Configuration();
114 TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
115
116 MappedStatement mappedStatement = new MappedStatement.Builder(config, "testSelect",
117 new StaticSqlSource(config, "some select statement"), SqlCommandType.SELECT).build();
118
119 Object parameterObject = 1;
120
121 BoundSql boundSql = new BoundSql(config, "some select statement", new ArrayList<ParameterMapping>() {
122 private static final long serialVersionUID = 1L;
123
124 {
125 add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(int.class)).build());
126 }
127 }, parameterObject) {
128 {
129 setAdditionalParameter("id", 2);
130 }
131 };
132
133 DefaultParameterHandler defaultParameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject,
134 boundSql);
135
136 PreparedStatement ps = mock(PreparedStatement.class);
137
138 defaultParameterHandler.setParameters(ps);
139
140 verify(ps).setInt(1, 2);
141 }
142
143 @Test
144 void parameterObjectGetPropertyValueWithNull() throws SQLException {
145 Configuration config = new Configuration();
146 TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
147
148 MappedStatement mappedStatement = new MappedStatement.Builder(config, "testSelect",
149 new StaticSqlSource(config, "some select statement"), SqlCommandType.SELECT).build();
150
151 Object parameterObject = null;
152
153 BoundSql boundSql = new BoundSql(config, "some select statement", new ArrayList<ParameterMapping>() {
154 private static final long serialVersionUID = 1L;
155
156 {
157 add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(int.class)).build());
158 }
159 }, parameterObject);
160
161 DefaultParameterHandler defaultParameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject,
162 boundSql);
163
164 PreparedStatement ps = mock(PreparedStatement.class);
165
166 defaultParameterHandler.setParameters(ps);
167
168 verify(ps).setNull(1, config.getJdbcTypeForNull().TYPE_CODE);
169 }
170
171 @Test
172 void parameterObjectGetPropertyValueWithTypeHandler() throws SQLException {
173 Configuration config = new Configuration();
174 TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
175
176 MappedStatement mappedStatement = new MappedStatement.Builder(config, "testSelect",
177 new StaticSqlSource(config, "some select statement"), SqlCommandType.SELECT).build();
178
179 Object parameterObject = 1;
180
181 BoundSql boundSql = new BoundSql(config, "some select statement", new ArrayList<ParameterMapping>() {
182 private static final long serialVersionUID = 1L;
183
184 {
185 add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(int.class)).build());
186 }
187 }, parameterObject);
188
189 DefaultParameterHandler defaultParameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject,
190 boundSql);
191
192 PreparedStatement ps = mock(PreparedStatement.class);
193
194 defaultParameterHandler.setParameters(ps);
195
196 verify(ps).setInt(1, (Integer) parameterObject);
197 }
198
199 @Test
200 void parameterObjectGetPropertyValueWithMetaObject() throws SQLException {
201 Configuration config = new Configuration();
202 TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
203
204 MappedStatement mappedStatement = new MappedStatement.Builder(config, "testSelect",
205 new StaticSqlSource(config, "some select statement"), SqlCommandType.SELECT).build();
206
207 Author parameterObject = new Author(-1, "cbegin", "******", "cbegin@nowhere.com", "N/A", Section.NEWS);
208
209 BoundSql boundSql = new BoundSql(config, "some select statement", new ArrayList<ParameterMapping>() {
210 private static final long serialVersionUID = 1L;
211
212 {
213 add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(int.class)).build());
214 add(new ParameterMapping.Builder(config, "username", registry.getTypeHandler(String.class)).build());
215 add(new ParameterMapping.Builder(config, "password", registry.getTypeHandler(String.class)).build());
216 add(new ParameterMapping.Builder(config, "email", registry.getTypeHandler(String.class)).build());
217 add(new ParameterMapping.Builder(config, "bio", registry.getTypeHandler(String.class))
218 .jdbcType(JdbcType.VARCHAR).build());
219 add(new ParameterMapping.Builder(config, "favouriteSection", registry.getTypeHandler(Section.class))
220 .jdbcType(JdbcType.VARCHAR).build());
221 }
222 }, parameterObject);
223
224 DefaultParameterHandler defaultParameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject,
225 boundSql);
226
227 PreparedStatement ps = mock(PreparedStatement.class);
228
229 defaultParameterHandler.setParameters(ps);
230
231 verify(ps).setInt(1, parameterObject.getId());
232 verify(ps).setString(2, parameterObject.getUsername());
233 verify(ps).setString(3, parameterObject.getPassword());
234 verify(ps).setString(4, parameterObject.getEmail());
235 verify(ps).setString(5, parameterObject.getBio());
236 verify(ps).setObject(6, parameterObject.getFavouriteSection().name(), JdbcType.VARCHAR.TYPE_CODE);
237 }
238
239 @Test
240 void parameterObjectGetPropertyValueWithMetaObjectAndCreateOnce() {
241 Author parameterObject = mock(Author.class);
242
243 Configuration mockConfig = mock(Configuration.class);
244
245 final ObjectFactory objectFactory = new DefaultObjectFactory();
246 final ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
247 final ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
248
249 when(mockConfig.getTypeHandlerRegistry()).thenReturn(new TypeHandlerRegistry(mockConfig));
250 when(mockConfig.getDefaultScriptingLanguageInstance()).thenReturn(new XMLLanguageDriver());
251 when(mockConfig.newMetaObject(parameterObject))
252 .thenReturn(MetaObject.forObject(parameterObject, objectFactory, objectWrapperFactory, reflectorFactory));
253
254 TypeHandlerRegistry registry = mockConfig.getTypeHandlerRegistry();
255
256 MappedStatement mappedStatement = new MappedStatement.Builder(mockConfig, "testSelect",
257 new StaticSqlSource(mockConfig, "some select statement"), SqlCommandType.SELECT).build();
258
259 BoundSql boundSql = new BoundSql(mockConfig, "some select statement", new ArrayList<ParameterMapping>() {
260 private static final long serialVersionUID = 1L;
261
262 {
263 add(new ParameterMapping.Builder(mockConfig, "id", registry.getTypeHandler(int.class))
264 .jdbcType(JdbcType.INTEGER).build());
265 add(new ParameterMapping.Builder(mockConfig, "username", registry.getTypeHandler(String.class))
266 .jdbcType(JdbcType.VARCHAR).build());
267 add(new ParameterMapping.Builder(mockConfig, "password", registry.getTypeHandler(String.class))
268 .jdbcType(JdbcType.VARCHAR).build());
269 add(new ParameterMapping.Builder(mockConfig, "email", registry.getTypeHandler(String.class))
270 .jdbcType(JdbcType.VARCHAR).build());
271 add(new ParameterMapping.Builder(mockConfig, "bio", registry.getTypeHandler(String.class))
272 .jdbcType(JdbcType.VARCHAR).build());
273 add(new ParameterMapping.Builder(mockConfig, "favouriteSection", registry.getTypeHandler(Section.class))
274 .jdbcType(JdbcType.VARCHAR).build());
275 }
276 }, parameterObject);
277
278 DefaultParameterHandler defaultParameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject,
279 boundSql);
280
281 PreparedStatement ps = mock(PreparedStatement.class);
282
283 defaultParameterHandler.setParameters(ps);
284
285 verify(parameterObject).getId();
286 verify(parameterObject).getUsername();
287 verify(parameterObject).getPassword();
288 verify(parameterObject).getEmail();
289 verify(parameterObject).getBio();
290 verify(parameterObject).getFavouriteSection();
291
292 verify(mockConfig).newMetaObject(parameterObject);
293 }
294 }