1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.submitted.sqlprovider;
17
18 import static org.junit.jupiter.api.Assertions.assertEquals;
19 import static org.junit.jupiter.api.Assertions.assertNotNull;
20 import static org.junit.jupiter.api.Assertions.assertNull;
21 import static org.junit.jupiter.api.Assertions.assertTrue;
22 import static org.junit.jupiter.api.Assertions.fail;
23
24 import java.io.Reader;
25 import java.lang.reflect.Method;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 import org.apache.ibatis.BaseDataTest;
33 import org.apache.ibatis.annotations.InsertProvider;
34 import org.apache.ibatis.annotations.DeleteProvider;
35 import org.apache.ibatis.annotations.Param;
36 import org.apache.ibatis.annotations.SelectProvider;
37 import org.apache.ibatis.annotations.UpdateProvider;
38 import org.apache.ibatis.binding.MapperMethod;
39 import org.apache.ibatis.builder.BuilderException;
40 import org.apache.ibatis.builder.annotation.ProviderContext;
41 import org.apache.ibatis.builder.annotation.ProviderSqlSource;
42 import org.apache.ibatis.io.Resources;
43 import org.apache.ibatis.session.Configuration;
44 import org.apache.ibatis.session.SqlSession;
45 import org.apache.ibatis.session.SqlSessionFactory;
46 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
47 import org.junit.jupiter.api.BeforeAll;
48 import org.junit.jupiter.api.Test;
49
50 class SqlProviderTest {
51
52 private static SqlSessionFactory sqlSessionFactory;
53 private static SqlSessionFactory sqlSessionFactoryForDerby;
54
55 @BeforeAll
56 static void setUp() throws Exception {
57
58 try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml")) {
59 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
60 sqlSessionFactory.getConfiguration().addMapper(StaticMethodSqlProviderMapper.class);
61 sqlSessionFactory.getConfiguration().addMapper(DatabaseIdMapper.class);
62 }
63
64 BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
65 "org/apache/ibatis/submitted/sqlprovider/CreateDB.sql");
66
67
68 try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml")) {
69 sqlSessionFactoryForDerby = new SqlSessionFactoryBuilder().build(reader, "development-derby");
70 sqlSessionFactoryForDerby.getConfiguration().addMapper(DatabaseIdMapper.class);
71 }
72 }
73
74
75 @Test
76 void shouldGetTwoUsers() {
77 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
78 Mapper mapper = sqlSession.getMapper(Mapper.class);
79 List<Integer> list = new ArrayList<>();
80 list.add(1);
81 list.add(3);
82 List<User> users = mapper.getUsers(list);
83 assertEquals(2, users.size());
84 assertEquals("User1", users.get(0).getName());
85 assertEquals("User3", users.get(1).getName());
86 }
87 }
88
89
90 @Test
91 void shouldGetOneUser() {
92 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
93 Mapper mapper = sqlSession.getMapper(Mapper.class);
94 {
95 User user = mapper.getUser(4);
96 assertNotNull(user);
97 assertEquals("User4", user.getName());
98 }
99 {
100 User user = mapper.getUser(null);
101 assertNull(user);
102 }
103 }
104 }
105
106
107 @Test
108 void shouldGetAllUsers() {
109 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
110 Mapper mapper = sqlSession.getMapper(Mapper.class);
111 List<User> users = mapper.getAllUsers();
112 assertEquals(4, users.size());
113 assertEquals("User1", users.get(0).getName());
114 assertEquals("User2", users.get(1).getName());
115 assertEquals("User3", users.get(2).getName());
116 assertEquals("User4", users.get(3).getName());
117 }
118 }
119
120
121 @Test
122 void shouldGetUsersByCriteria() {
123 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
124 Mapper mapper = sqlSession.getMapper(Mapper.class);
125 {
126 User criteria = new User();
127 criteria.setId(1);
128 List<User> users = mapper.getUsersByCriteria(criteria);
129 assertEquals(1, users.size());
130 assertEquals("User1", users.get(0).getName());
131 }
132 {
133 User criteria = new User();
134 criteria.setName("User");
135 List<User> users = mapper.getUsersByCriteria(criteria);
136 assertEquals(4, users.size());
137 assertEquals("User1", users.get(0).getName());
138 assertEquals("User2", users.get(1).getName());
139 assertEquals("User3", users.get(2).getName());
140 assertEquals("User4", users.get(3).getName());
141 }
142 }
143 }
144
145
146 @Test
147 void shouldGetUsersByCriteriaMap() {
148 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
149 Mapper mapper = sqlSession.getMapper(Mapper.class);
150 {
151 Map<String, Object> criteria = new HashMap<>();
152 criteria.put("id", 1);
153 List<User> users = mapper.getUsersByCriteriaMap(criteria);
154 assertEquals(1, users.size());
155 assertEquals("User1", users.get(0).getName());
156 }
157 {
158 Map<String, Object> criteria = new HashMap<>();
159 criteria.put("name", "User");
160 List<User> users = mapper.getUsersByCriteriaMap(criteria);
161 assertEquals(4, users.size());
162 assertEquals("User1", users.get(0).getName());
163 assertEquals("User2", users.get(1).getName());
164 assertEquals("User3", users.get(2).getName());
165 assertEquals("User4", users.get(3).getName());
166 }
167 }
168 }
169
170 @Test
171 void shouldGetUsersByCriteriaMapWithParam() {
172 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
173 Mapper mapper = sqlSession.getMapper(Mapper.class);
174 {
175 Map<String, Object> criteria = new HashMap<>();
176 criteria.put("id", 1);
177 List<User> users = mapper.getUsersByCriteriaMapWithParam(criteria);
178 assertEquals(1, users.size());
179 assertEquals("User1", users.get(0).getName());
180 }
181 {
182 Map<String, Object> criteria = new HashMap<>();
183 criteria.put("name", "User");
184 List<User> users = mapper.getUsersByCriteriaMapWithParam(criteria);
185 assertEquals(4, users.size());
186 assertEquals("User1", users.get(0).getName());
187 assertEquals("User2", users.get(1).getName());
188 assertEquals("User3", users.get(2).getName());
189 assertEquals("User4", users.get(3).getName());
190 }
191 }
192 }
193
194
195 @Test
196 void shouldGetUsersByName() {
197 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
198 Mapper mapper = sqlSession.getMapper(Mapper.class);
199 List<User> users = mapper.getUsersByName("User", "id DESC");
200 assertEquals(4, users.size());
201 assertEquals("User4", users.get(0).getName());
202 assertEquals("User3", users.get(1).getName());
203 assertEquals("User2", users.get(2).getName());
204 assertEquals("User1", users.get(3).getName());
205 }
206 }
207
208
209 @Test
210 void shouldGetUsersByNameUsingMap() {
211 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
212 Mapper mapper = sqlSession.getMapper(Mapper.class);
213 List<User> users = mapper.getUsersByNameUsingMap("User", "id DESC");
214 assertEquals(4, users.size());
215 assertEquals("User4", users.get(0).getName());
216 assertEquals("User3", users.get(1).getName());
217 assertEquals("User2", users.get(2).getName());
218 assertEquals("User1", users.get(3).getName());
219 }
220 }
221
222
223 @Test
224 void shouldGetUsersByNameWithParamNameAndOrderBy() {
225 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
226 Mapper mapper = sqlSession.getMapper(Mapper.class);
227 List<User> users = mapper.getUsersByNameWithParamNameAndOrderBy("User", "id DESC");
228 assertEquals(4, users.size());
229 assertEquals("User4", users.get(0).getName());
230 assertEquals("User3", users.get(1).getName());
231 assertEquals("User2", users.get(2).getName());
232 assertEquals("User1", users.get(3).getName());
233 }
234 }
235
236
237 @Test
238 void shouldGetUsersByNameWithParamNameUsingMap() {
239 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
240 Mapper mapper = sqlSession.getMapper(Mapper.class);
241 List<User> users = mapper.getUsersByNameWithParamNameAndOrderBy("User", "id DESC");
242 assertEquals(4, users.size());
243 assertEquals("User4", users.get(0).getName());
244 assertEquals("User3", users.get(1).getName());
245 assertEquals("User2", users.get(2).getName());
246 assertEquals("User1", users.get(3).getName());
247 }
248 }
249
250
251 @Test
252 void shouldGetUsersByNameWithParamName() {
253 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
254 Mapper mapper = sqlSession.getMapper(Mapper.class);
255 {
256 List<User> users = mapper.getUsersByNameWithParamName("User");
257 assertEquals(4, users.size());
258 assertEquals("User4", users.get(0).getName());
259 assertEquals("User3", users.get(1).getName());
260 assertEquals("User2", users.get(2).getName());
261 assertEquals("User1", users.get(3).getName());
262 }
263 {
264 List<User> users = mapper.getUsersByNameWithParamName(null);
265 assertEquals(4, users.size());
266 assertEquals("User4", users.get(0).getName());
267 assertEquals("User3", users.get(1).getName());
268 assertEquals("User2", users.get(2).getName());
269 assertEquals("User1", users.get(3).getName());
270 }
271 }
272 }
273
274 @Test
275 void methodNotFound() throws NoSuchMethodException {
276 try {
277 Class<?> mapperType = ErrorMapper.class;
278 Method mapperMethod = mapperType.getMethod("methodNotFound");
279 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
280 mapperMethod);
281 fail();
282 } catch (BuilderException e) {
283 assertTrue(e.getMessage().contains(
284 "Error creating SqlSource for SqlProvider. Method 'methodNotFound' not found in SqlProvider 'org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorSqlBuilder'."));
285 }
286 }
287
288 @Test
289 void methodOverload() throws NoSuchMethodException {
290 try {
291 Class<?> mapperType = ErrorMapper.class;
292 Method mapperMethod = mapperType.getMethod("methodOverload", String.class);
293 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
294 mapperMethod);
295 fail();
296 } catch (BuilderException e) {
297 assertTrue(e.getMessage().contains(
298 "Error creating SqlSource for SqlProvider. Method 'overload' is found multiple in SqlProvider 'org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorSqlBuilder'. Sql provider method can not overload."));
299 }
300 }
301
302 @Test
303 @SuppressWarnings("deprecation")
304 void notSqlProvider() throws NoSuchMethodException {
305 Object testAnnotation = getClass().getDeclaredMethod("notSqlProvider").getAnnotation(Test.class);
306 try {
307 new ProviderSqlSource(new Configuration(), testAnnotation);
308 fail();
309 } catch (BuilderException e) {
310 assertTrue(e.getMessage().contains(
311 "Error creating SqlSource for SqlProvider. Cause: java.lang.NoSuchMethodException: org.junit.jupiter.api.Test.type()"));
312 }
313 }
314
315 @Test
316 void omitType() throws NoSuchMethodException {
317 try {
318 Class<?> mapperType = ErrorMapper.class;
319 Method mapperMethod = mapperType.getMethod("omitType");
320 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
321 mapperMethod);
322 fail();
323 } catch (BuilderException e) {
324 assertTrue(e.getMessage().contains(
325 "Please specify either 'value' or 'type' attribute of @SelectProvider at the 'public abstract void org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorMapper.omitType()'."));
326 }
327 }
328
329 @Test
330 void differentTypeAndValue() throws NoSuchMethodException {
331 try {
332 Class<?> mapperType = ErrorMapper.class;
333 Method mapperMethod = mapperType.getMethod("differentTypeAndValue");
334 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(DeleteProvider.class), mapperType,
335 mapperMethod);
336 fail();
337 } catch (BuilderException e) {
338 assertTrue(e.getMessage().contains(
339 "Cannot specify different class on 'value' and 'type' attribute of @DeleteProvider at the 'public abstract void org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorMapper.differentTypeAndValue()'."));
340 }
341 }
342
343 @Test
344 void multipleProviderContext() throws NoSuchMethodException {
345 try {
346 Class<?> mapperType = ErrorMapper.class;
347 Method mapperMethod = mapperType.getMethod("multipleProviderContext");
348 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
349 mapperMethod);
350 fail();
351 } catch (BuilderException e) {
352 assertTrue(e.getMessage().contains(
353 "Error creating SqlSource for SqlProvider. ProviderContext found multiple in SqlProvider method (org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorSqlBuilder.multipleProviderContext). ProviderContext can not define multiple in SqlProvider method argument."));
354 }
355 }
356
357 @Test
358 void notSupportParameterObjectOnMultipleArguments() throws NoSuchMethodException {
359 try {
360 Class<?> mapperType = Mapper.class;
361 Method mapperMethod = mapperType.getMethod("getUsersByName", String.class, String.class);
362 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
363 mapperMethod).getBoundSql(new Object());
364 fail();
365 } catch (BuilderException e) {
366 assertTrue(e.getMessage().contains(
367 "Error invoking SqlProvider method 'public java.lang.String org.apache.ibatis.submitted.sqlprovider.OurSqlBuilder.buildGetUsersByNameQuery(java.lang.String,java.lang.String)' with specify parameter 'class java.lang.Object'. Cause: java.lang.IllegalArgumentException: wrong number of arguments"));
368 }
369 }
370
371 @Test
372 void notSupportParameterObjectOnNamedArgument() throws NoSuchMethodException {
373 try {
374 Class<?> mapperType = Mapper.class;
375 Method mapperMethod = mapperType.getMethod("getUsersByNameWithParamName", String.class);
376 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
377 mapperMethod).getBoundSql(new Object());
378 fail();
379 } catch (BuilderException e) {
380 assertTrue(e.getMessage().contains(
381 "Error invoking SqlProvider method 'public java.lang.String org.apache.ibatis.submitted.sqlprovider.OurSqlBuilder.buildGetUsersByNameWithParamNameQuery(java.lang.String)' with specify parameter 'class java.lang.Object'. Cause: java.lang.IllegalArgumentException: argument type mismatch"));
382 }
383 }
384
385 @Test
386 void invokeError() throws NoSuchMethodException {
387 try {
388 Class<?> mapperType = ErrorMapper.class;
389 Method mapperMethod = mapperType.getMethod("invokeError");
390 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
391 mapperMethod).getBoundSql(new Object());
392 fail();
393 } catch (BuilderException e) {
394 assertTrue(e.getMessage().contains(
395 "Error invoking SqlProvider method 'public java.lang.String org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorSqlBuilder.invokeError()' with specify parameter 'class java.lang.Object'. Cause: java.lang.UnsupportedOperationException: invokeError"));
396 }
397 }
398
399 @Test
400 void invokeNestedError() throws NoSuchMethodException {
401 try {
402 Class<?> mapperType = ErrorMapper.class;
403 Method mapperMethod = mapperType.getMethod("invokeNestedError");
404 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(SelectProvider.class), mapperType,
405 mapperMethod).getBoundSql(new Object());
406 fail();
407 } catch (BuilderException e) {
408 assertTrue(e.getMessage().contains(
409 "Error invoking SqlProvider method 'public java.lang.String org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorSqlBuilder.invokeNestedError()' with specify parameter 'class java.lang.Object'. Cause: java.lang.UnsupportedOperationException: invokeNestedError"));
410 }
411 }
412
413 @Test
414 void invalidArgumentsCombination() throws NoSuchMethodException {
415 try {
416 Class<?> mapperType = ErrorMapper.class;
417 Method mapperMethod = mapperType.getMethod("invalidArgumentsCombination", String.class);
418 new ProviderSqlSource(new Configuration(), mapperMethod.getAnnotation(DeleteProvider.class), mapperType,
419 mapperMethod).getBoundSql("foo");
420 fail();
421 } catch (BuilderException e) {
422 assertTrue(e.getMessage().contains(
423 "Cannot invoke SqlProvider method 'public java.lang.String org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorSqlBuilder.invalidArgumentsCombination(org.apache.ibatis.builder.annotation.ProviderContext,java.lang.String,java.lang.String)' with specify parameter 'class java.lang.String' because SqlProvider method arguments for 'public abstract void org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorMapper.invalidArgumentsCombination(java.lang.String)' is an invalid combination."));
424 }
425 }
426
427 @Test
428 void shouldInsertUser() {
429 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
430 Mapper mapper = sqlSession.getMapper(Mapper.class);
431 User user = new User();
432 user.setId(999);
433 user.setName("MyBatis");
434 mapper.insert(user);
435
436 User loadedUser = mapper.getUser(999);
437 assertEquals("MyBatis", loadedUser.getName());
438 }
439 }
440
441 @Test
442 void shouldUpdateUser() {
443 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
444 Mapper mapper = sqlSession.getMapper(Mapper.class);
445 User user = new User();
446 user.setId(999);
447 user.setName("MyBatis");
448 mapper.insert(user);
449
450 user.setName("MyBatis3");
451 mapper.update(user);
452
453 User loadedUser = mapper.getUser(999);
454 assertEquals("MyBatis3", loadedUser.getName());
455 }
456 }
457
458 @Test
459 void shouldDeleteUser() {
460 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
461 Mapper mapper = sqlSession.getMapper(Mapper.class);
462 User user = new User();
463 user.setId(999);
464 user.setName("MyBatis");
465 mapper.insert(user);
466
467 user.setName("MyBatis3");
468 mapper.delete(999);
469
470 User loadedUser = mapper.getUser(999);
471 assertNull(loadedUser);
472 }
473 }
474
475 @Test
476 void mapperProviderContextOnly() {
477 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
478 Mapper mapper = sqlSession.getMapper(Mapper.class);
479 assertEquals("User4", mapper.selectById(4).getName());
480 assertNull(mapper.selectActiveById(4));
481 }
482 }
483
484 @Test
485 void mapperOneParamAndProviderContext() {
486 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
487 Mapper mapper = sqlSession.getMapper(Mapper.class);
488 assertEquals(1, mapper.selectByName("User4").size());
489 assertEquals(0, mapper.selectActiveByName("User4").size());
490 }
491 }
492
493 @Test
494 void mapperMultipleParamAndProviderContextWithAtParam() {
495 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
496 Mapper mapper = sqlSession.getMapper(Mapper.class);
497 assertEquals(1, mapper.selectByIdAndNameWithAtParam(4, "User4").size());
498 assertEquals(0, mapper.selectActiveByIdAndNameWithAtParam(4, "User4").size());
499 }
500 }
501
502 @Test
503 void mapperMultipleParamAndProviderContext() {
504 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
505 Mapper mapper = sqlSession.getMapper(Mapper.class);
506 assertEquals(1, mapper.selectByIdAndName(4, "User4").size());
507 assertEquals(0, mapper.selectActiveByIdAndName(4, "User4").size());
508 }
509 }
510
511 @Test
512 void staticMethodNoArgument() {
513 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
514 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
515 assertEquals(1, mapper.noArgument());
516 }
517 }
518
519 @Test
520 void staticMethodOneArgument() {
521 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
522 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
523 assertEquals(10, mapper.oneArgument(10));
524 }
525 }
526
527 @Test
528 void staticMethodOnePrimitiveByteArgument() {
529 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
530 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
531 assertEquals((byte) 10, mapper.onePrimitiveByteArgument((byte) 10));
532 }
533 }
534
535 @Test
536 void staticMethodOnePrimitiveShortArgument() {
537 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
538 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
539 assertEquals((short) 10, mapper.onePrimitiveShortArgument((short) 10));
540 }
541 }
542
543 @Test
544 void staticMethodOnePrimitiveIntArgument() {
545 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
546 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
547 assertEquals(10, mapper.onePrimitiveIntArgument(10));
548 }
549 }
550
551 @Test
552 void staticMethodOnePrimitiveLongArgument() {
553 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
554 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
555 assertEquals(10L, mapper.onePrimitiveLongArgument(10L));
556 }
557 }
558
559 @Test
560 void staticMethodOnePrimitiveFloatArgument() {
561 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
562 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
563 assertEquals(10.1F, mapper.onePrimitiveFloatArgument(10.1F));
564 }
565 }
566
567 @Test
568 void staticMethodOnePrimitiveDoubleArgument() {
569 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
570 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
571 assertEquals(10.1D, mapper.onePrimitiveDoubleArgument(10.1D));
572 }
573 }
574
575 @Test
576 void staticMethodOnePrimitiveBooleanArgument() {
577 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
578 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
579 assertTrue(mapper.onePrimitiveBooleanArgument(true));
580 }
581 }
582
583 @Test
584 void staticMethodOnePrimitiveCharArgument() {
585 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
586 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
587 assertEquals('A', mapper.onePrimitiveCharArgument('A'));
588 }
589 }
590
591 @Test
592 void boxing() {
593 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
594 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
595 assertEquals(10, mapper.boxing(10));
596 }
597 }
598
599 @Test
600 void unboxing() {
601 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
602 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
603 assertEquals(100, mapper.unboxing(100));
604 }
605 }
606
607 @Test
608 void staticMethodMultipleArgument() {
609 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
610 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
611 assertEquals(2, mapper.multipleArgument(1, 1));
612 }
613 }
614
615 @Test
616 void staticMethodOnlyProviderContext() {
617 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
618 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
619 assertEquals("onlyProviderContext", mapper.onlyProviderContext());
620 }
621 }
622
623 @Test
624 void staticMethodOneArgumentAndProviderContext() {
625 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
626 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
627 assertEquals("oneArgumentAndProviderContext 100", mapper.oneArgumentAndProviderContext(100));
628 }
629 }
630
631 @Test
632 void mapAndProviderContext() {
633 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
634 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
635 assertEquals("mybatis", mapper.mapAndProviderContext("mybatis"));
636 }
637 }
638
639 @Test
640 void multipleMap() {
641 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
642 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
643 assertEquals("123456",
644 mapper.multipleMap(Collections.singletonMap("value", "123"), Collections.singletonMap("value", "456")));
645 }
646 }
647
648 @Test
649 void providerContextAndMap() {
650 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
651 StaticMethodSqlProviderMapper mapper = sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
652 assertEquals("mybatis", mapper.providerContextAndParamMap("mybatis"));
653 }
654 }
655
656 @Test
657 @SuppressWarnings("deprecation")
658 void keepBackwardCompatibilityOnDeprecatedConstructorWithAnnotation() throws NoSuchMethodException {
659 Class<?> mapperType = StaticMethodSqlProviderMapper.class;
660 Method mapperMethod = mapperType.getMethod("noArgument");
661 ProviderSqlSource sqlSource = new ProviderSqlSource(new Configuration(),
662 (Object) mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
663 assertEquals("SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS", sqlSource.getBoundSql(null).getSql());
664 }
665
666 @Test
667 void omitTypeWhenSpecifyDefaultType() throws NoSuchMethodException {
668 Class<?> mapperType = DefaultSqlProviderMapper.class;
669 Configuration configuration = new Configuration();
670 configuration.setDefaultSqlProviderType(DefaultSqlProviderMapper.SqlProvider.class);
671 {
672 Method mapperMethod = mapperType.getMethod("select", int.class);
673 String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(SelectProvider.class), mapperType,
674 mapperMethod).getBoundSql(1).getSql();
675 assertEquals("select name from foo where id = ?", sql);
676 }
677 {
678 Method mapperMethod = mapperType.getMethod("insert", String.class);
679 String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(InsertProvider.class), mapperType,
680 mapperMethod).getBoundSql("Taro").getSql();
681 assertEquals("insert into foo (name) values(?)", sql);
682 }
683 {
684 Method mapperMethod = mapperType.getMethod("update", int.class, String.class);
685 String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(UpdateProvider.class), mapperType,
686 mapperMethod).getBoundSql(Collections.emptyMap() ).getSql();
687 assertEquals("update foo set name = ? where id = ?", sql);
688 }
689 {
690 Method mapperMethod = mapperType.getMethod("delete", int.class);
691 String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(DeleteProvider.class), mapperType,
692 mapperMethod).getBoundSql(Collections.emptyMap() ).getSql();
693 assertEquals("delete from foo where id = ?", sql);
694 }
695 }
696
697 public interface DefaultSqlProviderMapper {
698
699 @SelectProvider
700 String select(int id);
701
702 @InsertProvider
703 void insert(String name);
704
705 @UpdateProvider
706 void update(int id, String name);
707
708 @DeleteProvider
709 void delete(int id);
710
711 class SqlProvider {
712
713 public static String provideSql(ProviderContext c) {
714 switch (c.getMapperMethod().getName()) {
715 case "select" :
716 return "select name from foo where id = #{id}";
717 case "insert" :
718 return "insert into foo (name) values(#{name})";
719 case "update" :
720 return "update foo set name = #{name} where id = #{id}";
721 default:
722 return "delete from foo where id = #{id}";
723 }
724 }
725
726 }
727
728 }
729
730 public interface ErrorMapper {
731 @SelectProvider(type = ErrorSqlBuilder.class, method = "methodNotFound")
732 void methodNotFound();
733
734 @SelectProvider(type = ErrorSqlBuilder.class, method = "overload")
735 void methodOverload(String value);
736
737 @SelectProvider(type = ErrorSqlBuilder.class, method = "invokeError")
738 void invokeError();
739
740 @SelectProvider(type = ErrorSqlBuilder.class, method = "invokeNestedError")
741 void invokeNestedError();
742
743 @SelectProvider(type = ErrorSqlBuilder.class, method = "multipleProviderContext")
744 void multipleProviderContext();
745
746 @SelectProvider
747 void omitType();
748
749 @DeleteProvider(value = String.class, type = Integer.class)
750 void differentTypeAndValue();
751
752 @DeleteProvider(type = ErrorSqlBuilder.class, method = "invalidArgumentsCombination")
753 void invalidArgumentsCombination(String value);
754
755 }
756
757 @SuppressWarnings("unused")
758 public static class ErrorSqlBuilder {
759 public void methodNotFound() {
760 throw new UnsupportedOperationException("methodNotFound");
761 }
762
763 public String overload() {
764 throw new UnsupportedOperationException("overload");
765 }
766
767 public String overload(String value) {
768 throw new UnsupportedOperationException("overload");
769 }
770
771 public String invokeError() {
772 throw new UnsupportedOperationException("invokeError");
773 }
774
775 public String invokeNestedError() {
776 throw new IllegalStateException(new UnsupportedOperationException("invokeNestedError"));
777 }
778
779 public String multipleProviderContext(ProviderContext providerContext1, ProviderContext providerContext2) {
780 throw new UnsupportedOperationException("multipleProviderContext");
781 }
782
783 public String invalidArgumentsCombination(ProviderContext providerContext, String value,
784 String unnecessaryArgument) {
785 return "";
786 }
787 }
788
789 public interface StaticMethodSqlProviderMapper {
790 @SelectProvider(type = SqlProvider.class, method = "noArgument")
791 int noArgument();
792
793 @SelectProvider(type = SqlProvider.class, method = "oneArgument")
794 int oneArgument(Integer value);
795
796 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveByteArgument")
797 byte onePrimitiveByteArgument(byte value);
798
799 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveShortArgument")
800 short onePrimitiveShortArgument(short value);
801
802 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveIntArgument")
803 int onePrimitiveIntArgument(int value);
804
805 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveLongArgument")
806 long onePrimitiveLongArgument(long value);
807
808 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveFloatArgument")
809 float onePrimitiveFloatArgument(float value);
810
811 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveDoubleArgument")
812 double onePrimitiveDoubleArgument(double value);
813
814 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveBooleanArgument")
815 boolean onePrimitiveBooleanArgument(boolean value);
816
817 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveCharArgument")
818 char onePrimitiveCharArgument(char value);
819
820 @SelectProvider(type = SqlProvider.class, method = "boxing")
821 int boxing(int value);
822
823 @SelectProvider(type = SqlProvider.class, method = "unboxing")
824 int unboxing(Integer value);
825
826 @SelectProvider(type = SqlProvider.class, method = "multipleArgument")
827 int multipleArgument(@Param("value1") Integer value1, @Param("value2") Integer value2);
828
829 @SelectProvider(type = SqlProvider.class, method = "onlyProviderContext")
830 String onlyProviderContext();
831
832 @SelectProvider(type = SqlProvider.class, method = "oneArgumentAndProviderContext")
833 String oneArgumentAndProviderContext(Integer value);
834
835 @SelectProvider(type = SqlProvider.class, method = "mapAndProviderContext")
836 String mapAndProviderContext(@Param("value") String value);
837
838 @SelectProvider(type = SqlProvider.class, method = "providerContextAndParamMap")
839 String providerContextAndParamMap(@Param("value") String value);
840
841 @SelectProvider(type = SqlProvider.class, method = "multipleMap")
842 String multipleMap(@Param("map1") Map<String, Object> map1, @Param("map2") Map<String, Object> map2);
843
844 @SuppressWarnings("unused")
845 class SqlProvider {
846
847 public static String noArgument() {
848 return "SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS";
849 }
850
851 public static StringBuilder oneArgument(Integer value) {
852 return new StringBuilder().append("SELECT ").append(value).append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
853 }
854
855 public static StringBuilder onePrimitiveByteArgument(byte value) {
856 return new StringBuilder().append("SELECT ").append(value).append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
857 }
858
859 public static StringBuilder onePrimitiveShortArgument(short value) {
860 return new StringBuilder().append("SELECT ").append(value).append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
861 }
862
863 public static StringBuilder onePrimitiveIntArgument(int value) {
864 return new StringBuilder().append("SELECT ").append(value).append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
865 }
866
867 public static StringBuilder onePrimitiveLongArgument(long value) {
868 return new StringBuilder().append("SELECT ").append(value).append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
869 }
870
871 public static StringBuilder onePrimitiveFloatArgument(float value) {
872 return new StringBuilder().append("SELECT ").append(value).append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
873 }
874
875 public static StringBuilder onePrimitiveDoubleArgument(double value) {
876 return new StringBuilder().append("SELECT ").append(value).append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
877 }
878
879 public static StringBuilder onePrimitiveBooleanArgument(boolean value) {
880 return new StringBuilder().append("SELECT ").append(value ? 1 : 0)
881 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
882 }
883
884 public static StringBuilder onePrimitiveCharArgument(char value) {
885 return new StringBuilder().append("SELECT '").append(value).append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
886 }
887
888 public static StringBuilder boxing(Integer value) {
889 return new StringBuilder().append("SELECT '").append(value).append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
890 }
891
892 public static StringBuilder unboxing(int value) {
893 return new StringBuilder().append("SELECT '").append(value).append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
894 }
895
896 public static CharSequence multipleArgument(@Param("value1") Integer value1, @Param("value2") Integer value2) {
897 return "SELECT " + (value1 + value2) + " FROM INFORMATION_SCHEMA.SYSTEM_USERS";
898 }
899
900 public static CharSequence onlyProviderContext(ProviderContext context) {
901 return new StringBuilder().append("SELECT '").append(context.getMapperMethod().getName())
902 .append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
903 }
904
905 public static String oneArgumentAndProviderContext(Integer value, ProviderContext context) {
906 return "SELECT '" + context.getMapperMethod().getName() + " " + value
907 + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
908 }
909
910 public static String mapAndProviderContext(Map<String, Object> map, ProviderContext context) {
911 return "SELECT '" + map.get("value") + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
912 }
913
914 public static String providerContextAndParamMap(ProviderContext context, MapperMethod.ParamMap<Object> map) {
915 return "SELECT '" + map.get("value") + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
916 }
917
918 public static String multipleMap(@Param("map1") Map<String, Object> map1,
919 @Param("map2") Map<String, Object> map2) {
920 return "SELECT '" + map1.get("value") + map2.get("value") + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
921 }
922
923 }
924
925 }
926
927 @Test
928 void shouldInsertUserSelective() {
929 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
930 Mapper mapper = sqlSession.getMapper(Mapper.class);
931 User user = new User();
932 user.setId(999);
933 mapper.insertSelective(user);
934
935 User loadedUser = mapper.getUser(999);
936 assertNull(loadedUser.getName());
937 }
938 }
939
940 @Test
941 void shouldUpdateUserSelective() {
942 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
943 Mapper mapper = sqlSession.getMapper(Mapper.class);
944 User user = new User();
945 user.setId(999);
946 user.setName("MyBatis");
947 mapper.insert(user);
948
949 user.setName(null);
950 mapper.updateSelective(user);
951
952 User loadedUser = mapper.getUser(999);
953 assertEquals("MyBatis", loadedUser.getName());
954 }
955 }
956
957 @Test
958 void mapperGetByEntity() {
959 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
960 Mapper mapper = sqlSession.getMapper(Mapper.class);
961 User query = new User();
962 query.setName("User4");
963 assertEquals(1, mapper.getByEntity(query).size());
964 query = new User();
965 query.setId(1);
966 assertEquals(1, mapper.getByEntity(query).size());
967 query = new User();
968 query.setId(1);
969 query.setName("User4");
970 assertEquals(0, mapper.getByEntity(query).size());
971 }
972 }
973
974 @Test
975 void shouldPassedDatabaseIdToProviderMethod() {
976 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
977 DatabaseIdMapper mapper = sqlSession.getMapper(DatabaseIdMapper.class);
978 assertEquals("hsql", mapper.selectDatabaseId());
979 }
980 try (SqlSession sqlSession = sqlSessionFactoryForDerby.openSession()) {
981 DatabaseIdMapper mapper = sqlSession.getMapper(DatabaseIdMapper.class);
982 assertEquals("derby", mapper.selectDatabaseId());
983 }
984 }
985
986 interface DatabaseIdMapper {
987 @SelectProvider(type = SqlProvider.class)
988 String selectDatabaseId();
989
990 @SuppressWarnings("unused")
991 class SqlProvider {
992 public static String provideSql(ProviderContext context) {
993 if ("hsql".equals(context.getDatabaseId())) {
994 return "SELECT '" + context.getDatabaseId() + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
995 } else {
996 return "SELECT '" + context.getDatabaseId() + "' FROM SYSIBM.SYSDUMMY1";
997 }
998 }
999 }
1000 }
1001
1002 }