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.DeleteProvider;
34 import org.apache.ibatis.annotations.Param;
35 import org.apache.ibatis.annotations.SelectProvider;
36 import org.apache.ibatis.binding.MapperMethod;
37 import org.apache.ibatis.builder.BuilderException;
38 import org.apache.ibatis.builder.annotation.ProviderContext;
39 import org.apache.ibatis.builder.annotation.ProviderSqlSource;
40 import org.apache.ibatis.io.Resources;
41 import org.apache.ibatis.session.Configuration;
42 import org.apache.ibatis.session.SqlSession;
43 import org.apache.ibatis.session.SqlSessionFactory;
44 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
45 import org.junit.jupiter.api.BeforeAll;
46 import org.junit.jupiter.api.Test;
47
48 class SqlProviderTest {
49
50 private static SqlSessionFactory sqlSessionFactory;
51 private static SqlSessionFactory sqlSessionFactoryForDerby;
52
53 @BeforeAll
54 static void setUp() throws Exception {
55
56 try (Reader reader = Resources
57 .getResourceAsReader("org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml")) {
58 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
59 sqlSessionFactory.getConfiguration().addMapper(StaticMethodSqlProviderMapper.class);
60 sqlSessionFactory.getConfiguration().addMapper(DatabaseIdMapper.class);
61 }
62
63 BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
64 "org/apache/ibatis/submitted/sqlprovider/CreateDB.sql");
65
66
67 try (Reader reader = Resources
68 .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 Usered/sqlprovider/User.html#User">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 Usered/sqlprovider/User.html#User">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(),
280 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
281 fail();
282 } catch (BuilderException e) {
283 assertTrue(e.getMessage().contains("Error creating SqlSource for SqlProvider. Method 'methodNotFound' not found in SqlProvider 'org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorSqlBuilder'."));
284 }
285 }
286
287 @Test
288 void methodOverload() throws NoSuchMethodException {
289 try {
290 Class<?> mapperType = ErrorMapper.class;
291 Method mapperMethod = mapperType.getMethod("methodOverload", String.class);
292 new ProviderSqlSource(new Configuration(),
293 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
294 fail();
295 } catch (BuilderException e) {
296 assertTrue(e.getMessage().contains("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."));
297 }
298 }
299
300 @Test
301 @SuppressWarnings("deprecation")
302 void notSqlProvider() throws NoSuchMethodException {
303 Object testAnnotation = getClass().getDeclaredMethod("notSqlProvider").getAnnotation(Test.class);
304 try {
305 new ProviderSqlSource(new Configuration(), testAnnotation);
306 fail();
307 } catch (BuilderException e) {
308 assertTrue(e.getMessage().contains("Error creating SqlSource for SqlProvider. Cause: java.lang.NoSuchMethodException: org.junit.jupiter.api.Test.type()"));
309 }
310 }
311
312 @Test
313 void omitType() throws NoSuchMethodException {
314 try {
315 Class<?> mapperType = ErrorMapper.class;
316 Method mapperMethod = mapperType.getMethod("omitType");
317 new ProviderSqlSource(new Configuration(),
318 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
319 fail();
320 } catch (BuilderException e) {
321 assertTrue(e.getMessage().contains("Please specify either 'value' or 'type' attribute of @SelectProvider at the 'public abstract void org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorMapper.omitType()'."));
322 }
323 }
324
325 @Test
326 void differentTypeAndValue() throws NoSuchMethodException {
327 try {
328 Class<?> mapperType = ErrorMapper.class;
329 Method mapperMethod = mapperType.getMethod("differentTypeAndValue");
330 new ProviderSqlSource(new Configuration(),
331 mapperMethod.getAnnotation(DeleteProvider.class), mapperType, mapperMethod);
332 fail();
333 } catch (BuilderException e) {
334 assertTrue(e.getMessage().contains("Cannot specify different class on 'value' and 'type' attribute of @DeleteProvider at the 'public abstract void org.apache.ibatis.submitted.sqlprovider.SqlProviderTest$ErrorMapper.differentTypeAndValue()'."));
335 }
336 }
337
338 @Test
339 void multipleProviderContext() throws NoSuchMethodException {
340 try {
341 Class<?> mapperType = ErrorMapper.class;
342 Method mapperMethod = mapperType.getMethod("multipleProviderContext");
343 new ProviderSqlSource(new Configuration(),
344 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
345 fail();
346 } catch (BuilderException e) {
347 assertTrue(e.getMessage().contains("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."));
348 }
349 }
350
351 @Test
352 void notSupportParameterObjectOnMultipleArguments() throws NoSuchMethodException {
353 try {
354 Class<?> mapperType = Mapper.class;
355 Method mapperMethod = mapperType.getMethod("getUsersByName", String.class, String.class);
356 new ProviderSqlSource(new Configuration(),
357 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod)
358 .getBoundSql(new Object());
359 fail();
360 } catch (BuilderException e) {
361 assertTrue(e.getMessage().contains("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"));
362 }
363 }
364
365 @Test
366 void notSupportParameterObjectOnNamedArgument() throws NoSuchMethodException {
367 try {
368 Class<?> mapperType = Mapper.class;
369 Method mapperMethod = mapperType.getMethod("getUsersByNameWithParamName", String.class);
370 new ProviderSqlSource(new Configuration(),
371 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod)
372 .getBoundSql(new Object());
373 fail();
374 } catch (BuilderException e) {
375 assertTrue(e.getMessage().contains("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"));
376 }
377 }
378
379 @Test
380 void invokeError() throws NoSuchMethodException {
381 try {
382 Class<?> mapperType = ErrorMapper.class;
383 Method mapperMethod = mapperType.getMethod("invokeError");
384 new ProviderSqlSource(new Configuration(),
385 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod)
386 .getBoundSql(new Object());
387 fail();
388 } catch (BuilderException e) {
389 assertTrue(e.getMessage().contains("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"));
390 }
391 }
392
393 @Test
394 void invokeNestedError() throws NoSuchMethodException {
395 try {
396 Class<?> mapperType = ErrorMapper.class;
397 Method mapperMethod = mapperType.getMethod("invokeNestedError");
398 new ProviderSqlSource(new Configuration(),
399 mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod)
400 .getBoundSql(new Object());
401 fail();
402 } catch (BuilderException e) {
403 assertTrue(e.getMessage().contains("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"));
404 }
405 }
406
407 @Test
408 void invalidArgumentsCombination() throws NoSuchMethodException {
409 try {
410 Class<?> mapperType = ErrorMapper.class;
411 Method mapperMethod = mapperType.getMethod("invalidArgumentsCombination", String.class);
412 new ProviderSqlSource(new Configuration(),
413 mapperMethod.getAnnotation(DeleteProvider.class), mapperType, mapperMethod)
414 .getBoundSql("foo");
415 fail();
416 } catch (BuilderException e) {
417 assertTrue(e.getMessage().contains("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."));
418 }
419 }
420
421 @Test
422 void shouldInsertUser() {
423 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
424 Mapper mapper = sqlSession.getMapper(Mapper.class);
425 Usermitted/sqlprovider/User.html#User">User user = new User();
426 user.setId(999);
427 user.setName("MyBatis");
428 mapper.insert(user);
429
430 User loadedUser = mapper.getUser(999);
431 assertEquals("MyBatis", loadedUser.getName());
432 }
433 }
434
435 @Test
436 void shouldUpdateUser() {
437 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
438 Mapper mapper = sqlSession.getMapper(Mapper.class);
439 Usermitted/sqlprovider/User.html#User">User user = new User();
440 user.setId(999);
441 user.setName("MyBatis");
442 mapper.insert(user);
443
444 user.setName("MyBatis3");
445 mapper.update(user);
446
447 User loadedUser = mapper.getUser(999);
448 assertEquals("MyBatis3", loadedUser.getName());
449 }
450 }
451
452 @Test
453 void shouldDeleteUser() {
454 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
455 Mapper mapper = sqlSession.getMapper(Mapper.class);
456 Usermitted/sqlprovider/User.html#User">User user = new User();
457 user.setId(999);
458 user.setName("MyBatis");
459 mapper.insert(user);
460
461 user.setName("MyBatis3");
462 mapper.delete(999);
463
464 User loadedUser = mapper.getUser(999);
465 assertNull(loadedUser);
466 }
467 }
468
469 @Test
470 void mapperProviderContextOnly() {
471 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
472 Mapper mapper = sqlSession.getMapper(Mapper.class);
473 assertEquals("User4", mapper.selectById(4).getName());
474 assertNull(mapper.selectActiveById(4));
475 }
476 }
477
478 @Test
479 void mapperOneParamAndProviderContext() {
480 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
481 Mapper mapper = sqlSession.getMapper(Mapper.class);
482 assertEquals(1, mapper.selectByName("User4").size());
483 assertEquals(0, mapper.selectActiveByName("User4").size());
484 }
485 }
486
487 @Test
488 void mapperMultipleParamAndProviderContextWithAtParam() {
489 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
490 Mapper mapper = sqlSession.getMapper(Mapper.class);
491 assertEquals(1, mapper.selectByIdAndNameWithAtParam(4,"User4").size());
492 assertEquals(0, mapper.selectActiveByIdAndNameWithAtParam(4,"User4").size());
493 }
494 }
495
496 @Test
497 void mapperMultipleParamAndProviderContext() {
498 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
499 Mapper mapper = sqlSession.getMapper(Mapper.class);
500 assertEquals(1, mapper.selectByIdAndName(4,"User4").size());
501 assertEquals(0, mapper.selectActiveByIdAndName(4,"User4").size());
502 }
503 }
504
505 @Test
506 void staticMethodNoArgument() {
507 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
508 StaticMethodSqlProviderMapper mapper =
509 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
510 assertEquals(1, mapper.noArgument());
511 }
512 }
513
514 @Test
515 void staticMethodOneArgument() {
516 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
517 StaticMethodSqlProviderMapper mapper =
518 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
519 assertEquals(10, mapper.oneArgument(10));
520 }
521 }
522
523 @Test
524 void staticMethodOnePrimitiveByteArgument() {
525 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
526 StaticMethodSqlProviderMapper mapper =
527 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
528 assertEquals((byte) 10, mapper.onePrimitiveByteArgument((byte) 10));
529 }
530 }
531
532 @Test
533 void staticMethodOnePrimitiveShortArgument() {
534 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
535 StaticMethodSqlProviderMapper mapper =
536 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
537 assertEquals((short) 10, mapper.onePrimitiveShortArgument((short) 10));
538 }
539 }
540
541 @Test
542 void staticMethodOnePrimitiveIntArgument() {
543 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
544 StaticMethodSqlProviderMapper mapper =
545 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
546 assertEquals(10, mapper.onePrimitiveIntArgument(10));
547 }
548 }
549
550 @Test
551 void staticMethodOnePrimitiveLongArgument() {
552 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
553 StaticMethodSqlProviderMapper mapper =
554 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 =
563 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
564 assertEquals(10.1F, mapper.onePrimitiveFloatArgument(10.1F));
565 }
566 }
567
568 @Test
569 void staticMethodOnePrimitiveDoubleArgument() {
570 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
571 StaticMethodSqlProviderMapper mapper =
572 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
573 assertEquals(10.1D, mapper.onePrimitiveDoubleArgument(10.1D));
574 }
575 }
576
577 @Test
578 void staticMethodOnePrimitiveBooleanArgument() {
579 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
580 StaticMethodSqlProviderMapper mapper =
581 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
582 assertTrue(mapper.onePrimitiveBooleanArgument(true));
583 }
584 }
585
586 @Test
587 void staticMethodOnePrimitiveCharArgument() {
588 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
589 StaticMethodSqlProviderMapper mapper =
590 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
591 assertEquals('A', mapper.onePrimitiveCharArgument('A'));
592 }
593 }
594
595 @Test
596 void boxing() {
597 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
598 StaticMethodSqlProviderMapper mapper =
599 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
600 assertEquals(10, mapper.boxing(10));
601 }
602 }
603
604 @Test
605 void unboxing() {
606 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
607 StaticMethodSqlProviderMapper mapper =
608 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
609 assertEquals(100, mapper.unboxing(100));
610 }
611 }
612
613 @Test
614 void staticMethodMultipleArgument() {
615 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
616 StaticMethodSqlProviderMapper mapper =
617 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
618 assertEquals(2, mapper.multipleArgument(1, 1));
619 }
620 }
621
622 @Test
623 void staticMethodOnlyProviderContext() {
624 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
625 StaticMethodSqlProviderMapper mapper =
626 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
627 assertEquals("onlyProviderContext", mapper.onlyProviderContext());
628 }
629 }
630
631 @Test
632 void staticMethodOneArgumentAndProviderContext() {
633 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
634 StaticMethodSqlProviderMapper mapper =
635 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
636 assertEquals("oneArgumentAndProviderContext 100", mapper.oneArgumentAndProviderContext(100));
637 }
638 }
639
640 @Test
641 void mapAndProviderContext() {
642 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
643 StaticMethodSqlProviderMapper mapper =
644 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
645 assertEquals("mybatis", mapper.mapAndProviderContext("mybatis"));
646 }
647 }
648
649 @Test
650 void multipleMap() {
651 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
652 StaticMethodSqlProviderMapper mapper =
653 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
654 assertEquals("123456", mapper.multipleMap(Collections.singletonMap("value", "123"), Collections.singletonMap("value", "456")));
655 }
656 }
657
658 @Test
659 void providerContextAndMap() {
660 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
661 StaticMethodSqlProviderMapper mapper =
662 sqlSession.getMapper(StaticMethodSqlProviderMapper.class);
663 assertEquals("mybatis", mapper.providerContextAndParamMap("mybatis"));
664 }
665 }
666
667 @Test
668 @SuppressWarnings("deprecation")
669 void keepBackwardCompatibilityOnDeprecatedConstructorWithAnnotation() throws NoSuchMethodException {
670 Class<?> mapperType = StaticMethodSqlProviderMapper.class;
671 Method mapperMethod = mapperType.getMethod("noArgument");
672 ProviderSqlSource sqlSource = new ProviderSqlSource(new Configuration(), (Object)mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
673 assertEquals("SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS", sqlSource.getBoundSql(null).getSql());
674 }
675
676 public interface ErrorMapper {
677 @SelectProvider(type = ErrorSqlBuilder.class, method = "methodNotFound")
678 void methodNotFound();
679
680 @SelectProvider(type = ErrorSqlBuilder.class, method = "overload")
681 void methodOverload(String value);
682
683 @SelectProvider(type = ErrorSqlBuilder.class, method = "invokeError")
684 void invokeError();
685
686 @SelectProvider(type = ErrorSqlBuilder.class, method = "invokeNestedError")
687 void invokeNestedError();
688
689 @SelectProvider(type = ErrorSqlBuilder.class, method = "multipleProviderContext")
690 void multipleProviderContext();
691
692 @SelectProvider
693 void omitType();
694
695 @DeleteProvider(value = String.class, type = Integer.class)
696 void differentTypeAndValue();
697
698 @DeleteProvider(type = ErrorSqlBuilder.class, method = "invalidArgumentsCombination")
699 void invalidArgumentsCombination(String value);
700
701 }
702
703 @SuppressWarnings("unused")
704 public static class ErrorSqlBuilder {
705 public void methodNotFound() {
706 throw new UnsupportedOperationException("methodNotFound");
707 }
708
709 public String overload() {
710 throw new UnsupportedOperationException("overload");
711 }
712
713 public String overload(String value) {
714 throw new UnsupportedOperationException("overload");
715 }
716
717 public String invokeError() {
718 throw new UnsupportedOperationException("invokeError");
719 }
720
721 public String invokeNestedError() {
722 throw new IllegalStateException(new UnsupportedOperationException("invokeNestedError"));
723 }
724
725 public String multipleProviderContext(ProviderContext providerContext1, ProviderContext providerContext2) {
726 throw new UnsupportedOperationException("multipleProviderContext");
727 }
728
729 public String invalidArgumentsCombination(ProviderContext providerContext, String value, String unnecessaryArgument) {
730 return "";
731 }
732 }
733
734 public interface StaticMethodSqlProviderMapper {
735 @SelectProvider(type = SqlProvider.class, method = "noArgument")
736 int noArgument();
737
738 @SelectProvider(type = SqlProvider.class, method = "oneArgument")
739 int oneArgument(Integer value);
740
741 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveByteArgument")
742 byte onePrimitiveByteArgument(byte value);
743
744 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveShortArgument")
745 short onePrimitiveShortArgument(short value);
746
747 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveIntArgument")
748 int onePrimitiveIntArgument(int value);
749
750 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveLongArgument")
751 long onePrimitiveLongArgument(long value);
752
753 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveFloatArgument")
754 float onePrimitiveFloatArgument(float value);
755
756 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveDoubleArgument")
757 double onePrimitiveDoubleArgument(double value);
758
759 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveBooleanArgument")
760 boolean onePrimitiveBooleanArgument(boolean value);
761
762 @SelectProvider(type = SqlProvider.class, method = "onePrimitiveCharArgument")
763 char onePrimitiveCharArgument(char value);
764
765 @SelectProvider(type = SqlProvider.class, method = "boxing")
766 int boxing(int value);
767
768 @SelectProvider(type = SqlProvider.class, method = "unboxing")
769 int unboxing(Integer value);
770
771 @SelectProvider(type = SqlProvider.class, method = "multipleArgument")
772 int multipleArgument(@Param("value1") Integer value1, @Param("value2") Integer value2);
773
774 @SelectProvider(type = SqlProvider.class, method = "onlyProviderContext")
775 String onlyProviderContext();
776
777 @SelectProvider(type = SqlProvider.class, method = "oneArgumentAndProviderContext")
778 String oneArgumentAndProviderContext(Integer value);
779
780 @SelectProvider(type = SqlProvider.class, method = "mapAndProviderContext")
781 String mapAndProviderContext(@Param("value") String value);
782
783 @SelectProvider(type = SqlProvider.class, method = "providerContextAndParamMap")
784 String providerContextAndParamMap(@Param("value") String value);
785
786 @SelectProvider(type = SqlProvider.class, method = "multipleMap")
787 String multipleMap(@Param("map1") Map<String, Object> map1, @Param("map2") Map<String, Object> map2);
788
789 @SuppressWarnings("unused")
790 class SqlProvider {
791
792 public static String noArgument() {
793 return "SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS";
794 }
795
796 public static StringBuilder oneArgument(Integer value) {
797 return new StringBuilder().append("SELECT ").append(value)
798 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
799 }
800
801 public static StringBuilder onePrimitiveByteArgument(byte value) {
802 return new StringBuilder().append("SELECT ").append(value)
803 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
804 }
805
806 public static StringBuilder onePrimitiveShortArgument(short value) {
807 return new StringBuilder().append("SELECT ").append(value)
808 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
809 }
810
811 public static StringBuilder onePrimitiveIntArgument(int value) {
812 return new StringBuilder().append("SELECT ").append(value)
813 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
814 }
815
816 public static StringBuilder onePrimitiveLongArgument(long value) {
817 return new StringBuilder().append("SELECT ").append(value)
818 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
819 }
820
821 public static StringBuilder onePrimitiveFloatArgument(float value) {
822 return new StringBuilder().append("SELECT ").append(value)
823 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
824 }
825
826 public static StringBuilder onePrimitiveDoubleArgument(double value) {
827 return new StringBuilder().append("SELECT ").append(value)
828 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
829 }
830
831 public static StringBuilder onePrimitiveBooleanArgument(boolean value) {
832 return new StringBuilder().append("SELECT ").append(value ? 1 : 0)
833 .append(" FROM INFORMATION_SCHEMA.SYSTEM_USERS");
834 }
835
836 public static StringBuilder onePrimitiveCharArgument(char value) {
837 return new StringBuilder().append("SELECT '").append(value)
838 .append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
839 }
840
841 public static StringBuilder boxing(Integer value) {
842 return new StringBuilder().append("SELECT '").append(value)
843 .append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
844 }
845
846 public static StringBuilder unboxing(int value) {
847 return new StringBuilder().append("SELECT '").append(value)
848 .append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
849 }
850
851 public static CharSequence multipleArgument(@Param("value1") Integer value1,
852 @Param("value2") Integer value2) {
853 return "SELECT " + (value1 + value2) + " FROM INFORMATION_SCHEMA.SYSTEM_USERS";
854 }
855
856 public static CharSequence onlyProviderContext(ProviderContext context) {
857 return new StringBuilder().append("SELECT '").append(context.getMapperMethod().getName())
858 .append("' FROM INFORMATION_SCHEMA.SYSTEM_USERS");
859 }
860
861 public static String oneArgumentAndProviderContext(Integer value, ProviderContext context) {
862 return "SELECT '" + context.getMapperMethod().getName() + " " + value
863 + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
864 }
865
866 public static String mapAndProviderContext(Map<String, Object> map, ProviderContext context) {
867 return "SELECT '" + map.get("value") + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
868 }
869
870 public static String providerContextAndParamMap(ProviderContext context, MapperMethod.ParamMap<Object> map) {
871 return "SELECT '" + map.get("value") + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
872 }
873
874 public static String multipleMap(@Param("map1") Map<String, Object> map1, @Param("map2") Map<String, Object> map2) {
875 return "SELECT '" + map1.get("value") + map2.get("value") + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
876 }
877
878 }
879
880 }
881
882 @Test
883 void shouldInsertUserSelective() {
884 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
885 Mapper mapper = sqlSession.getMapper(Mapper.class);
886 Usermitted/sqlprovider/User.html#User">User user = new User();
887 user.setId(999);
888 mapper.insertSelective(user);
889
890 User loadedUser = mapper.getUser(999);
891 assertNull(loadedUser.getName());
892 }
893 }
894
895
896 @Test
897 void shouldUpdateUserSelective() {
898 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
899 Mapper mapper = sqlSession.getMapper(Mapper.class);
900 Usermitted/sqlprovider/User.html#User">User user = new User();
901 user.setId(999);
902 user.setName("MyBatis");
903 mapper.insert(user);
904
905 user.setName(null);
906 mapper.updateSelective(user);
907
908 User loadedUser = mapper.getUser(999);
909 assertEquals("MyBatis", loadedUser.getName());
910 }
911 }
912
913 @Test
914 void mapperGetByEntity() {
915 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
916 Mapper mapper = sqlSession.getMapper(Mapper.class);
917 Useritted/sqlprovider/User.html#User">User query = new User();
918 query.setName("User4");
919 assertEquals(1, mapper.getByEntity(query).size());
920 query = new User();
921 query.setId(1);
922 assertEquals(1, mapper.getByEntity(query).size());
923 query = new User();
924 query.setId(1);
925 query.setName("User4");
926 assertEquals(0, mapper.getByEntity(query).size());
927 }
928 }
929
930 @Test
931 void shouldPassedDatabaseIdToProviderMethod() {
932 try (SqlSession sqlSession = sqlSessionFactory.openSession()){
933 DatabaseIdMapper mapper = sqlSession.getMapper(DatabaseIdMapper.class);
934 assertEquals("hsql", mapper.selectDatabaseId());
935 }
936 try (SqlSession sqlSession = sqlSessionFactoryForDerby.openSession()){
937 DatabaseIdMapper mapper = sqlSession.getMapper(DatabaseIdMapper.class);
938 assertEquals("derby", mapper.selectDatabaseId());
939 }
940 }
941
942 interface DatabaseIdMapper {
943 @SelectProvider(type = SqlProvider.class)
944 String selectDatabaseId();
945
946 @SuppressWarnings("unused")
947 class SqlProvider {
948 public static String provideSql(ProviderContext context) {
949 if ("hsql".equals(context.getDatabaseId())) {
950 return "SELECT '" + context.getDatabaseId() + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
951 } else {
952 return "SELECT '" + context.getDatabaseId() + "' FROM SYSIBM.SYSDUMMY1";
953 }
954 }
955 }
956 }
957
958 }