1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.dynamic.sql.select;
17
18 import static org.assertj.core.api.Assertions.assertThat;
19 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
20 import static org.junit.jupiter.api.Assertions.assertAll;
21 import static org.mybatis.dynamic.sql.SqlBuilder.*;
22
23 import java.sql.JDBCType;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.junit.jupiter.api.Test;
31 import org.mybatis.dynamic.sql.SortSpecification;
32 import org.mybatis.dynamic.sql.SqlColumn;
33 import org.mybatis.dynamic.sql.SqlTable;
34 import org.mybatis.dynamic.sql.exception.NonRenderingWhereClauseException;
35 import org.mybatis.dynamic.sql.render.RenderingStrategies;
36 import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
37
38 class SelectStatementTest {
39
40 static final SqlTable table = SqlTable.of("foo");
41 static final SqlColumn<Date> column1 = table.column("column1", JDBCType.DATE);
42 static final SqlColumn<Integer> column2 = table.column("column2", JDBCType.INTEGER);
43 static final SqlColumn<String> column3 = table.column("column3", JDBCType.VARCHAR);
44
45 @Test
46 void testSimpleCriteria() {
47 Date d = new Date();
48
49 SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2)
50 .from(table, "a")
51 .where(column1, isEqualTo(d), and(column2, isEqualTo(33)))
52 .or(column2, isEqualTo(4))
53 .and(column2, isLessThan(3))
54 .build()
55 .render(RenderingStrategies.MYBATIS3);
56
57 String expectedFullStatement = "select a.column1 as A_COLUMN1, a.column2 "
58 + "from foo a "
59 + "where (a.column1 = #{parameters.p1,jdbcType=DATE} and a.column2 = #{parameters.p2,jdbcType=INTEGER}) or a.column2 = #{parameters.p3,jdbcType=INTEGER} and a.column2 < #{parameters.p4,jdbcType=INTEGER}";
60
61 Map<String, Object> parameters = selectStatement.getParameters();
62
63 assertAll(
64 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
65 () -> assertThat(parameters).containsEntry("p1", d),
66 () -> assertThat(parameters).containsEntry("p2", 33),
67 () -> assertThat(parameters).containsEntry("p3", 4),
68 () -> assertThat(parameters).containsEntry("p4", 3)
69 );
70 }
71
72 @Test
73 void testComplexCriteria() {
74 Date d = new Date();
75
76 SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2)
77 .from(table, "a")
78 .where(column1, isEqualTo(d))
79 .or(column2, isEqualTo(4))
80 .and(column2, isLessThan(3))
81 .or(column2, isEqualTo(4), and(column2, isEqualTo(6)))
82 .and(column2, isLessThan(3), or(column1, isEqualTo(d)))
83 .build()
84 .render(RenderingStrategies.MYBATIS3);
85
86 String expectedFullStatement = "select a.column1 as A_COLUMN1, a.column2 "
87 + "from foo a "
88 + "where a.column1 = #{parameters.p1,jdbcType=DATE}"
89 + " or a.column2 = #{parameters.p2,jdbcType=INTEGER}"
90 + " and a.column2 < #{parameters.p3,jdbcType=INTEGER}"
91 + " or (a.column2 = #{parameters.p4,jdbcType=INTEGER} and a.column2 = #{parameters.p5,jdbcType=INTEGER})"
92 + " and (a.column2 < #{parameters.p6,jdbcType=INTEGER} or a.column1 = #{parameters.p7,jdbcType=DATE})";
93
94 Map<String, Object> parameters = selectStatement.getParameters();
95
96 assertAll(
97 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
98 () -> assertThat(parameters).containsEntry("p1", d),
99 () -> assertThat(parameters).containsEntry("p2", 4),
100 () -> assertThat(parameters).containsEntry("p3", 3),
101 () -> assertThat(parameters).containsEntry("p4", 4),
102 () -> assertThat(parameters).containsEntry("p5", 6),
103 () -> assertThat(parameters).containsEntry("p6", 3),
104 () -> assertThat(parameters).containsEntry("p7", d)
105 );
106 }
107
108 @Test
109 void testOrderBySingleColumnAscending() {
110 Date d = new Date();
111
112 SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2)
113 .from(table, "a")
114 .where(column1, isEqualTo(d))
115 .orderBy(column1)
116 .build()
117 .render(RenderingStrategies.MYBATIS3);
118
119 String expectedFullStatement = "select a.column1 as A_COLUMN1, a.column2 "
120 + "from foo a "
121 + "where a.column1 = #{parameters.p1,jdbcType=DATE} "
122 + "order by column1";
123
124 Map<String, Object> parameters = selectStatement.getParameters();
125
126 assertAll(
127 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
128 () -> assertThat(parameters).containsEntry("p1", d)
129 );
130 }
131
132 @Test
133 void testOrderBySingleColumnDescending() {
134 Date d = new Date();
135
136 SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2)
137 .from(table, "a")
138 .where(column1, isEqualTo(d))
139 .orderBy(column2.descending())
140 .build()
141 .render(RenderingStrategies.MYBATIS3);
142
143 String expectedFullStatement = "select a.column1 as A_COLUMN1, a.column2 "
144 + "from foo a "
145 + "where a.column1 = #{parameters.p1,jdbcType=DATE} "
146 + "order by column2 DESC";
147
148 Map<String, Object> parameters = selectStatement.getParameters();
149
150 assertAll(
151 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
152 () -> assertThat(parameters).containsEntry("p1", d)
153 );
154 }
155
156 @Test
157 void testOrderByMultipleColumns() {
158 Date d = new Date();
159
160 SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2)
161 .from(table, "a")
162 .where(column1, isEqualTo(d))
163 .orderBy(column2.descending(), column1)
164 .build()
165 .render(RenderingStrategies.MYBATIS3);
166
167 String expectedFullStatement = "select a.column1 as A_COLUMN1, a.column2 "
168 + "from foo a "
169 + "where a.column1 = #{parameters.p1,jdbcType=DATE} "
170 + "order by column2 DESC, column1";
171
172 Map<String, Object> parameters = selectStatement.getParameters();
173
174 assertAll(
175 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
176 () -> assertThat(parameters).containsEntry("p1", d)
177 );
178 }
179
180 @Test
181 void testOrderByMultipleColumnsWithCollection() {
182 Collection<SortSpecification> orderByColumns = List.of(column2.descending(), column1);
183
184 SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2)
185 .from(table, "a")
186 .orderBy(orderByColumns)
187 .build()
188 .render(RenderingStrategies.MYBATIS3);
189
190 String expectedFullStatement = "select a.column1 as A_COLUMN1, a.column2 "
191 + "from foo a "
192 + "order by column2 DESC, column1";
193
194 assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement);
195 }
196
197 @Test
198 void testDistinct() {
199 Date d = new Date();
200
201 SelectStatementProvider selectStatement = selectDistinct(column1.as("A_COLUMN1"), column2)
202 .from(table, "a")
203 .where(column1, isEqualTo(d))
204 .orderBy(column2.descending(), column1)
205 .build()
206 .render(RenderingStrategies.MYBATIS3);
207
208 String expectedFullStatement = "select distinct a.column1 as A_COLUMN1, a.column2 "
209 + "from foo a "
210 + "where a.column1 = #{parameters.p1,jdbcType=DATE} "
211 + "order by column2 DESC, column1";
212
213 Map<String, Object> parameters = selectStatement.getParameters();
214
215 assertAll(
216 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
217 () -> assertThat(parameters).containsEntry("p1", d)
218 );
219 }
220
221 @Test
222 void testCount() {
223 Date d = new Date();
224
225 SelectStatementProvider selectStatement = select(count())
226 .from(table, "a")
227 .where(column1, isEqualTo(d))
228 .build()
229 .render(RenderingStrategies.MYBATIS3);
230
231 String expectedFullStatement = "select count(*) "
232 + "from foo a "
233 + "where a.column1 = #{parameters.p1,jdbcType=DATE}";
234
235 Map<String, Object> parameters = selectStatement.getParameters();
236
237 assertAll(
238 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
239 () -> assertThat(parameters).containsEntry("p1", d)
240 );
241 }
242
243 @Test
244 void testNoWhere() {
245 SelectStatementProvider selectStatement = select(count())
246 .from(table, "a")
247 .build()
248 .render(RenderingStrategies.MYBATIS3);
249
250 String expectedFullStatement = "select count(*) "
251 + "from foo a";
252
253 Map<String, Object> parameters = selectStatement.getParameters();
254
255 assertAll(
256 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
257 () -> assertThat(parameters).isEmpty()
258 );
259 }
260
261 @Test
262 void testGroupBySingleColumn() {
263 Date d = new Date();
264
265 SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2)
266 .from(table, "a")
267 .where(column1, isEqualTo(d))
268 .groupBy(column2)
269 .build()
270 .render(RenderingStrategies.MYBATIS3);
271
272 String expectedFullStatement = "select a.column1 as A_COLUMN1, a.column2 "
273 + "from foo a "
274 + "where a.column1 = #{parameters.p1,jdbcType=DATE} "
275 + "group by a.column2";
276
277 Map<String, Object> parameters = selectStatement.getParameters();
278
279 assertAll(
280 () -> assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedFullStatement),
281 () -> assertThat(parameters).containsEntry("p1", d)
282 );
283 }
284
285 @Test
286 void testNotInEmptyList() {
287 List<String> emptyList = Collections.emptyList();
288 SelectModel selectModel = select(column1, column3)
289 .from(table, "a")
290 .where(column3, isNotInWhenPresent(emptyList))
291 .build();
292
293 assertThatExceptionOfType(RuntimeException.class).isThrownBy(() ->
294 selectModel.render(RenderingStrategies.MYBATIS3)
295 );
296 }
297
298 @Test
299 void testInWhenPresentEmptyList() {
300 List<String> emptyList = Collections.emptyList();
301 SelectModel selectModel = select(column1, column3)
302 .from(table, "a")
303 .where(column3, isInWhenPresent(emptyList))
304 .build();
305
306 assertThatExceptionOfType(RuntimeException.class).isThrownBy(() ->
307 selectModel.render(RenderingStrategies.MYBATIS3)
308 );
309 }
310
311 @Test
312 void testInCaseInsensitiveEmptyList() {
313 SelectModel selectModel = select(column1, column3)
314 .from(table, "a")
315 .where(column3, isInCaseInsensitiveWhenPresent(Collections.emptyList()))
316 .build();
317
318 assertThatExceptionOfType(RuntimeException.class).isThrownBy(() ->
319 selectModel.render(RenderingStrategies.MYBATIS3)
320 );
321 }
322
323 @Test
324 void testInCaseInsensitiveWhenPresentEmptyList() {
325 SelectModel selectModel = select(column1, column3)
326 .from(table, "a")
327 .where(column3, isInCaseInsensitiveWhenPresent(Collections.emptyList()))
328 .build();
329
330 assertThatExceptionOfType(NonRenderingWhereClauseException.class).isThrownBy(() ->
331 selectModel.render(RenderingStrategies.MYBATIS3)
332 );
333 }
334
335 @Test
336 void testNotInWhenPresentEmptyList() {
337 List<String> emptyList = Collections.emptyList();
338 SelectModel selectModel = select(column1, column3)
339 .from(table, "a")
340 .where(column3, isNotInWhenPresent(emptyList))
341 .build();
342
343 assertThatExceptionOfType(NonRenderingWhereClauseException.class).isThrownBy(() ->
344 selectModel.render(RenderingStrategies.MYBATIS3)
345 );
346 }
347
348 @Test
349 void testNotInCaseInsensitiveWhenPresentEmptyList() {
350 SelectModel selectModel = select(column1, column3)
351 .from(table, "a")
352 .where(column3, isNotInCaseInsensitiveWhenPresent(Collections.emptyList()))
353 .build();
354
355 assertThatExceptionOfType(NonRenderingWhereClauseException.class).isThrownBy(() ->
356 selectModel.render(RenderingStrategies.MYBATIS3)
357 );
358 }
359
360 @Test
361 void testInWhenPresentNullList() {
362 SelectStatementProvider selectStatement = select(column1, column3)
363 .from(table)
364 .where(column3, isInWhenPresent((Collection<String>) null))
365 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
366 .build()
367 .render(RenderingStrategies.MYBATIS3);
368
369 assertThat(selectStatement.getSelectStatement()).isEqualTo("select column1, column3 from foo");
370 }
371
372 @Test
373 void testInCaseInsensitiveWhenPresentNullList() {
374 SelectStatementProvider selectStatement = select(column1, column3)
375 .from(table)
376 .where(column3, isInCaseInsensitiveWhenPresent((Collection<String>) null))
377 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
378 .build()
379 .render(RenderingStrategies.MYBATIS3);
380
381 assertThat(selectStatement.getSelectStatement()).isEqualTo("select column1, column3 from foo");
382 }
383
384 @Test
385 void testNotInWhenPresentNullList() {
386 SelectStatementProvider selectStatement = select(column1, column3)
387 .from(table)
388 .where(column3, isNotInWhenPresent((Collection<String>) null))
389 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
390 .build()
391 .render(RenderingStrategies.MYBATIS3);
392
393 assertThat(selectStatement.getSelectStatement()).isEqualTo("select column1, column3 from foo");
394 }
395
396 @Test
397 void testNotInCaseInsensitiveWhenPresentNullList() {
398 SelectStatementProvider selectStatement = select(column1, column3)
399 .from(table)
400 .where(column3, isNotInCaseInsensitiveWhenPresent((Collection<String>) null))
401 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
402 .build()
403 .render(RenderingStrategies.MYBATIS3);
404
405 assertThat(selectStatement.getSelectStatement()).isEqualTo("select column1, column3 from foo");
406 }
407 }