1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.executor;
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
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import javassist.util.proxy.Proxy;
28
29 import javax.sql.DataSource;
30
31 import org.apache.ibatis.BaseDataTest;
32 import org.apache.ibatis.domain.blog.Author;
33 import org.apache.ibatis.domain.blog.Blog;
34 import org.apache.ibatis.domain.blog.Post;
35 import org.apache.ibatis.domain.blog.Section;
36 import org.apache.ibatis.mapping.MappedStatement;
37 import org.apache.ibatis.session.Configuration;
38 import org.apache.ibatis.session.RowBounds;
39 import org.apache.ibatis.transaction.Transaction;
40 import org.apache.ibatis.transaction.jdbc.JdbcTransaction;
41 import org.junit.jupiter.api.BeforeAll;
42 import org.junit.jupiter.api.Test;
43
44 class BaseExecutorTest extends BaseDataTest {
45 protected final Configuration config;
46 private static DataSource ds;
47
48 @BeforeAll
49 static void setup() throws Exception {
50 ds = createBlogDataSource();
51 }
52
53 BaseExecutorTest() {
54 config = new Configuration();
55 config.setLazyLoadingEnabled(true);
56 config.setUseGeneratedKeys(false);
57 config.setMultipleResultSetsEnabled(true);
58 config.setUseColumnLabel(true);
59 config.setDefaultStatementTimeout(5000);
60 config.setDefaultFetchSize(100);
61 }
62
63 @Test
64 void shouldInsertNewAuthorWithBeforeAutoKey() throws Exception {
65
66 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
67 try {
68 Author author = new Author(-1, "someone", "******", "someone@apache.org", null, Section.NEWS);
69 MappedStatement insertStatement = ExecutorTestHelper.prepareInsertAuthorMappedStatementWithBeforeAutoKey(config);
70 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config);
71 int rows = executor.update(insertStatement, author);
72 assertTrue(rows > 0 || rows == BatchExecutor.BATCH_UPDATE_RETURN_VALUE);
73 if (rows == BatchExecutor.BATCH_UPDATE_RETURN_VALUE) {
74 executor.flushStatements();
75 }
76 assertEquals(123456, author.getId());
77 if (author.getId() != BatchExecutor.BATCH_UPDATE_RETURN_VALUE) {
78 List<Author> authors = executor.query(selectStatement, author.getId(), RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
79 executor.rollback(true);
80 assertEquals(1, authors.size());
81 assertEquals(author.toString(), authors.get(0).toString());
82 assertTrue(author.getId() >= 10000);
83 }
84 } finally {
85 executor.rollback(true);
86 executor.close(false);
87 }
88 }
89
90 @Test
91 void shouldInsertNewAuthor() throws Exception {
92
93 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
94 try {
95 Author author = new Author(99, "someone", "******", "someone@apache.org", null, Section.NEWS);
96 MappedStatement insertStatement = ExecutorTestHelper.prepareInsertAuthorMappedStatement(config);
97 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config);
98 int rows = executor.update(insertStatement, author);
99 List<Author> authors = executor.query(selectStatement, 99, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
100 executor.flushStatements();
101 executor.rollback(true);
102 assertEquals(1, authors.size());
103 assertEquals(author.toString(), authors.get(0).toString());
104 assertTrue(1 == rows || BatchExecutor.BATCH_UPDATE_RETURN_VALUE == rows);
105 } finally {
106 executor.rollback(true);
107 executor.close(false);
108 }
109 }
110
111 @Test
112 void shouldSelectAllAuthorsAutoMapped() throws Exception {
113
114 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
115 try {
116 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectAllAuthorsAutoMappedStatement(config);
117 List<Author> authors = executor.query(selectStatement, null, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
118 assertEquals(2, authors.size());
119 Author author = authors.get(0);
120
121
122 assertEquals(101, author.getId());
123 assertEquals("jim", author.getUsername());
124 assertEquals("jim@ibatis.apache.org", author.getEmail());
125 assertEquals("", author.getBio());
126 assertEquals(Section.NEWS, author.getFavouriteSection());
127 } finally {
128 executor.rollback(true);
129 executor.close(false);
130 }
131 }
132
133 @Test
134 void shouldInsertNewAuthorWithAutoKey() throws Exception {
135
136 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
137 try {
138 Author author = new Author(-1, "someone", "******", "someone@apache.org", null, Section.NEWS);
139 MappedStatement insertStatement = ExecutorTestHelper.prepareInsertAuthorMappedStatementWithAutoKey(config);
140 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config);
141 int rows = executor.update(insertStatement, author);
142 assertTrue(rows > 0 || rows == BatchExecutor.BATCH_UPDATE_RETURN_VALUE);
143 if (rows == BatchExecutor.BATCH_UPDATE_RETURN_VALUE) {
144 executor.flushStatements();
145 }
146 assertTrue(-1 != author.getId());
147 if (author.getId() != BatchExecutor.BATCH_UPDATE_RETURN_VALUE) {
148 List<Author> authors = executor.query(selectStatement, author.getId(), RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
149 executor.rollback(true);
150 assertEquals(1, authors.size());
151 assertEquals(author.toString(), authors.get(0).toString());
152 assertTrue(author.getId() >= 10000);
153 }
154 } finally {
155 executor.rollback(true);
156 executor.close(false);
157 }
158 }
159
160 @Test
161 void shouldInsertNewAuthorByProc() throws Exception {
162
163 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
164 try {
165 Author author = new Author(97, "someone", "******", "someone@apache.org", null, null);
166 MappedStatement insertStatement = ExecutorTestHelper.prepareInsertAuthorProc(config);
167 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config);
168 int rows = executor.update(insertStatement, author);
169 List<Author> authors = executor.query(selectStatement, 97, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
170 executor.flushStatements();
171 executor.rollback(true);
172 assertEquals(1, authors.size());
173 assertEquals(author.toString(), authors.get(0).toString());
174 } finally {
175 executor.rollback(true);
176 executor.close(false);
177 }
178 }
179
180 @Test
181 void shouldInsertNewAuthorUsingSimpleNonPreparedStatements() throws Exception {
182
183 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
184 try {
185 Author author = new Author(99, "someone", "******", "someone@apache.org", null, null);
186 MappedStatement insertStatement = ExecutorTestHelper.createInsertAuthorWithIDof99MappedStatement(config);
187 MappedStatement selectStatement = ExecutorTestHelper.createSelectAuthorWithIDof99MappedStatement(config);
188 int rows = executor.update(insertStatement, null);
189 List<Author> authors = executor.query(selectStatement, 99, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
190 executor.flushStatements();
191 executor.rollback(true);
192 assertEquals(1, authors.size());
193 assertEquals(author.toString(), authors.get(0).toString());
194 assertTrue(1 == rows || BatchExecutor.BATCH_UPDATE_RETURN_VALUE == rows);
195 } finally {
196 executor.rollback(true);
197 executor.close(false);
198 }
199 }
200
201 @Test
202 void shouldUpdateAuthor() throws Exception {
203
204 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
205 try {
206 Author author = new Author(101, "someone", "******", "someone@apache.org", null, Section.NEWS);
207 MappedStatement updateStatement = ExecutorTestHelper.prepareUpdateAuthorMappedStatement(config);
208 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config);
209 int rows = executor.update(updateStatement, author);
210 List<Author> authors = executor.query(selectStatement, 101, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
211 executor.flushStatements();
212 executor.rollback(true);
213 assertEquals(1, authors.size());
214 assertEquals(author.toString(), authors.get(0).toString());
215 assertTrue(1 == rows || BatchExecutor.BATCH_UPDATE_RETURN_VALUE == rows);
216 } finally {
217 executor.rollback(true);
218 executor.close(false);
219 }
220 }
221
222 @Test
223 void shouldDeleteAuthor() throws Exception {
224
225 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
226 try {
227 Author author = new Author(101, null, null, null, null, null);
228 MappedStatement deleteStatement = ExecutorTestHelper.prepareDeleteAuthorMappedStatement(config);
229 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config);
230 int rows = executor.update(deleteStatement, author);
231 List<Author> authors = executor.query(selectStatement, 101, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
232 executor.flushStatements();
233 executor.rollback(true);
234 assertEquals(0, authors.size());
235 assertTrue(1 == rows || BatchExecutor.BATCH_UPDATE_RETURN_VALUE == rows);
236 } finally {
237 executor.rollback(true);
238 executor.close(false);
239 }
240 }
241
242 @Test
243 void shouldSelectDiscriminatedPost() throws Exception {
244
245 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
246 try {
247 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectDiscriminatedPost(config);
248 List<Map<String,String>> products = executor.query(selectStatement, null, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
249 assertEquals(5, products.size());
250 for (Map<String,String> m : products) {
251 if ("IMAGES".equals(m.get("SECTION"))) {
252 assertNull(m.get("subject"));
253 } else {
254 assertNotNull(m.get("subject"));
255 }
256 }
257 } finally {
258 executor.close(false);
259 }
260 }
261
262 @Test
263 void shouldSelect2DiscriminatedPosts() throws Exception {
264
265 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
266 try {
267 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectDiscriminatedPost(config);
268 List<Map<String,String>> products = executor.query(selectStatement, null, new RowBounds(2, 2), Executor.NO_RESULT_HANDLER);
269 assertEquals(2, products.size());
270 for (Map<String,String> m : products) {
271 if ("IMAGES".equals(m.get("SECTION"))) {
272 assertNull(m.get("subject"));
273 } else {
274 assertNotNull(m.get("subject"));
275 }
276 }
277 } finally {
278 executor.rollback(true);
279 executor.close(false);
280 }
281 }
282
283 @Test
284 void shouldSelectTwoSetsOfAuthorsViaProc() throws Exception {
285 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
286 try {
287 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectTwoSetsOfAuthorsProc(config);
288 List<List<Author>> authorSets = executor.query(selectStatement, new HashMap<String, Object>() {
289 {
290 put("id1", 101);
291 put("id2", 102);
292 }
293 }, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
294 assertEquals(2, authorSets.size());
295 for (List<Author> authors : authorSets) {
296 assertEquals(2, authors.size());
297 for (Object author : authors) {
298 assertTrue(author instanceof Author);
299 }
300 }
301 } finally {
302 executor.rollback(true);
303 executor.close(false);
304 }
305 }
306
307 @Test
308 void shouldSelectAuthorViaOutParams() throws Exception {
309
310 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
311 try {
312 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectAuthorViaOutParams(config);
313 Author author = new Author(102, null, null, null, null, null);
314 executor.query(selectStatement, author, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
315 assertEquals("sally", author.getUsername());
316 assertEquals("********", author.getPassword());
317 assertEquals("sally@ibatis.apache.org", author.getEmail());
318 assertNull(author.getBio());
319 } catch (ExecutorException e) {
320 if (executor instanceof CachingExecutor) {
321
322 assertTrue(e.getMessage().contains("OUT params is not supported"));
323 } else {
324 throw e;
325 }
326 } finally {
327 executor.rollback(true);
328 executor.close(false);
329 }
330 }
331
332 @Test
333 void shouldFetchPostsForBlog() throws Exception {
334
335 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
336 try {
337 MappedStatement selectBlog = ExecutorTestHelper.prepareComplexSelectBlogMappedStatement(config);
338 MappedStatement selectPosts = ExecutorTestHelper.prepareSelectPostsForBlogMappedStatement(config);
339 config.addMappedStatement(selectBlog);
340 config.addMappedStatement(selectPosts);
341 List<Post> posts = executor.query(selectPosts, 1, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
342 executor.flushStatements();
343 assertEquals(2, posts.size());
344 assertTrue(posts.get(1) instanceof Proxy);
345 assertNotNull(posts.get(1).getBlog());
346 assertEquals(1, posts.get(1).getBlog().getId());
347 executor.rollback(true);
348 } finally {
349 executor.rollback(true);
350 executor.close(false);
351 }
352 }
353
354 @Test
355 void shouldFetchOneOrphanedPostWithNoBlog() throws Exception {
356
357 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
358 try {
359 MappedStatement selectBlog = ExecutorTestHelper.prepareComplexSelectBlogMappedStatement(config);
360 MappedStatement selectPost = ExecutorTestHelper.prepareSelectPostMappedStatement(config);
361 config.addMappedStatement(selectBlog);
362 config.addMappedStatement(selectPost);
363 List<Post> posts = executor.query(selectPost, 5, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
364 executor.flushStatements();
365 executor.rollback(true);
366 assertEquals(1, posts.size());
367 Post post = posts.get(0);
368 assertNull(post.getBlog());
369 } finally {
370 executor.rollback(true);
371 executor.close(false);
372 }
373 }
374
375 @Test
376 void shouldFetchPostWithBlogWithCompositeKey() throws Exception {
377
378 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
379 try {
380 MappedStatement selectBlog = ExecutorTestHelper.prepareSelectBlogByIdAndAuthor(config);
381 MappedStatement selectPost = ExecutorTestHelper.prepareSelectPostWithBlogByAuthorMappedStatement(config);
382 config.addMappedStatement(selectBlog);
383 config.addMappedStatement(selectPost);
384 List<Post> posts = executor.query(selectPost, 2, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
385 executor.flushStatements();
386 assertEquals(1, posts.size());
387 Post post = posts.get(0);
388 assertNotNull(post.getBlog());
389 assertEquals(101, post.getBlog().getAuthor().getId());
390 executor.rollback(true);
391 } finally {
392 executor.rollback(true);
393 executor.close(false);
394 }
395 }
396
397 @Test
398 void shouldFetchComplexBlogs() throws Exception {
399
400 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
401 try {
402 MappedStatement selectBlog = ExecutorTestHelper.prepareComplexSelectBlogMappedStatement(config);
403 MappedStatement selectPosts = ExecutorTestHelper.prepareSelectPostsForBlogMappedStatement(config);
404 config.addMappedStatement(selectBlog);
405 config.addMappedStatement(selectPosts);
406 List<Blog> blogs = executor.query(selectBlog, 1, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
407 executor.flushStatements();
408 assertEquals(1, blogs.size());
409 assertNotNull(blogs.get(0).getPosts());
410 assertEquals(2, blogs.get(0).getPosts().size());
411 assertEquals(1, blogs.get(0).getPosts().get(1).getBlog().getPosts().get(1).getBlog().getId());
412 executor.rollback(true);
413 } finally {
414 executor.rollback(true);
415 executor.close(false);
416 }
417 }
418
419 @Test
420 void shouldMapConstructorResults() throws Exception {
421
422 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
423 try {
424 MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatementWithConstructorResults(config);
425 List<Author> authors = executor.query(selectStatement, 102, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
426 executor.flushStatements();
427 executor.rollback(true);
428 assertEquals(1, authors.size());
429
430 Author author = authors.get(0);
431 assertEquals(102, author.getId());
432 } finally {
433 executor.rollback(true);
434 executor.close(false);
435 }
436 }
437
438 @Test
439 void shouldClearDeferredLoads() throws Exception {
440
441 Executor executor = createExecutor(new JdbcTransaction(ds, null, false));
442 try {
443 MappedStatement selectBlog = ExecutorTestHelper.prepareComplexSelectBlogMappedStatement(config);
444 MappedStatement selectPosts = ExecutorTestHelper.prepareSelectPostsForBlogMappedStatement(config);
445 config.addMappedStatement(selectBlog);
446 config.addMappedStatement(selectPosts);
447 MappedStatement selectAuthor = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config);
448 MappedStatement insertAuthor = ExecutorTestHelper.prepareInsertAuthorMappedStatement(config);
449
450
451 executor.query(selectPosts, 1, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
452
453 Author author = new Author(-1, "someone", "******", "someone@apache.org", null, Section.NEWS);
454 executor.update(insertAuthor, author);
455 executor.query(selectAuthor, -1, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
456 executor.flushStatements();
457 executor.rollback(true);
458 } finally {
459 executor.rollback(true);
460 executor.close(false);
461 }
462 }
463
464 protected Executor createExecutor(Transaction transaction) {
465 return new SimpleExecutor(config, transaction);
466 }
467
468 }