1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package examples.animal.data;
17
18 import static examples.animal.data.AnimalDataDynamicSqlSupport.animalData;
19 import static examples.animal.data.AnimalDataDynamicSqlSupport.animalName;
20 import static examples.animal.data.AnimalDataDynamicSqlSupport.id;
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
23 import static org.mybatis.dynamic.sql.SqlBuilder.isIn;
24 import static org.mybatis.dynamic.sql.SqlBuilder.isInCaseInsensitive;
25 import static org.mybatis.dynamic.sql.SqlBuilder.isInCaseInsensitiveWhenPresent;
26 import static org.mybatis.dynamic.sql.SqlBuilder.isInWhenPresent;
27 import static org.mybatis.dynamic.sql.SqlBuilder.isNotIn;
28 import static org.mybatis.dynamic.sql.SqlBuilder.isNotInCaseInsensitive;
29 import static org.mybatis.dynamic.sql.SqlBuilder.isNotInCaseInsensitiveWhenPresent;
30 import static org.mybatis.dynamic.sql.SqlBuilder.isNotInWhenPresent;
31 import static org.mybatis.dynamic.sql.SqlBuilder.select;
32
33 import java.io.InputStream;
34 import java.io.InputStreamReader;
35 import java.sql.Connection;
36 import java.sql.DriverManager;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.List;
40 import java.util.Map;
41
42 import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
43 import org.apache.ibatis.jdbc.ScriptRunner;
44 import org.apache.ibatis.mapping.Environment;
45 import org.apache.ibatis.session.Configuration;
46 import org.apache.ibatis.session.SqlSession;
47 import org.apache.ibatis.session.SqlSessionFactory;
48 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
49 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
50 import org.junit.jupiter.api.BeforeEach;
51 import org.junit.jupiter.api.Test;
52 import org.mybatis.dynamic.sql.exception.InvalidSqlException;
53 import org.mybatis.dynamic.sql.render.RenderingStrategies;
54 import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
55 import org.mybatis.dynamic.sql.util.Messages;
56 import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper;
57
58 class VariousListConditionsTest {
59 private static final String JDBC_URL = "jdbc:hsqldb:mem:aname";
60 private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver";
61
62 private SqlSessionFactory sqlSessionFactory;
63
64 @BeforeEach
65 void setup() throws Exception {
66 Class.forName(JDBC_DRIVER);
67 try (InputStream is = getClass().getResourceAsStream("/examples/animal/data/CreateAnimalData.sql")) {
68 assert is != null;
69 try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "");
70 InputStreamReader isr = new InputStreamReader(is)) {
71 ScriptRunner sr = new ScriptRunner(connection);
72 sr.setLogWriter(null);
73 sr.runScript(isr);
74 }
75 }
76
77 UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
78 Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
79 Configuration config = new Configuration(environment);
80 config.addMapper(CommonSelectMapper.class);
81 sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
82 }
83
84 @Test
85 void testInWithNull() {
86 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
87 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
88
89 SelectStatementProvider selectStatement = select(id, animalName)
90 .from(animalData)
91 .where(id, isInWhenPresent(2, 3, null))
92 .orderBy(id)
93 .build()
94 .render(RenderingStrategies.MYBATIS3);
95
96 assertThat(selectStatement.getSelectStatement()).isEqualTo(
97 "select id, animal_name from AnimalData where id " +
98 "in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) " +
99 "order by id"
100 );
101 assertThat(selectStatement.getParameters()).containsEntry("p1", 2);
102 assertThat(selectStatement.getParameters()).containsEntry("p2", 3);
103
104 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
105 assertThat(rows).hasSize(2);
106
107 assertThat(rows.get(0)).containsEntry("ID", 2);
108 }
109 }
110
111 @Test
112 void testInWhenPresentWithNull() {
113 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
114 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
115
116 SelectStatementProvider selectStatement = select(id, animalName)
117 .from(animalData)
118 .where(id, isInWhenPresent(2, 3, null))
119 .orderBy(id)
120 .build()
121 .render(RenderingStrategies.MYBATIS3);
122
123 assertThat(selectStatement.getSelectStatement()).isEqualTo(
124 "select id, animal_name from AnimalData " +
125 "where id in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) " +
126 "order by id"
127 );
128 assertThat(selectStatement.getParameters()).containsEntry("p1", 2);
129 assertThat(selectStatement.getParameters()).containsEntry("p2", 3);
130
131 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
132 assertThat(rows).hasSize(2);
133
134 assertThat(rows.get(0)).containsEntry("ID", 2);
135 }
136 }
137
138 @Test
139 void testInWithEmptyList() {
140 var selectModel = select(id, animalName)
141 .from(animalData)
142 .where(id, isIn(Collections.emptyList()))
143 .orderBy(id)
144 .build();
145
146 assertThatExceptionOfType(InvalidSqlException.class)
147 .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3))
148 .withMessage(Messages.getString("ERROR.44", "IsIn"));
149 }
150
151 @Test
152 void testInWhenPresentWithEmptyList() {
153 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
154 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
155
156 SelectStatementProvider selectStatement = select(id, animalName)
157 .from(animalData)
158 .where(id, isInWhenPresent(Collections.emptyList()))
159 .orderBy(id)
160 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
161 .build()
162 .render(RenderingStrategies.MYBATIS3);
163
164 assertThat(selectStatement.getSelectStatement()).isEqualTo(
165 "select id, animal_name from AnimalData " +
166 "order by id");
167
168 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
169 assertThat(rows).hasSize(65);
170
171 assertThat(rows.get(0)).containsEntry("ID", 1);
172 }
173 }
174
175 @Test
176 void testInWhenPresentWithNullList() {
177 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
178 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
179
180 SelectStatementProvider selectStatement = select(id, animalName)
181 .from(animalData)
182 .where(id, isInWhenPresent((Collection<Integer>) null))
183 .orderBy(id)
184 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
185 .build()
186 .render(RenderingStrategies.MYBATIS3);
187
188 assertThat(selectStatement.getSelectStatement()).isEqualTo(
189 "select id, animal_name from AnimalData " +
190 "order by id");
191
192 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
193 assertThat(rows).hasSize(65);
194
195 assertThat(rows.get(0)).containsEntry("ID", 1);
196 }
197 }
198
199 @Test
200 void testInWhenPresentMap() {
201 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
202 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
203
204 SelectStatementProvider selectStatement = select(id, animalName)
205 .from(animalData)
206 .where(id, isInWhenPresent(2, 3).map(i -> i + 3))
207 .orderBy(id)
208 .build()
209 .render(RenderingStrategies.MYBATIS3);
210
211 assertThat(selectStatement.getSelectStatement()).isEqualTo(
212 "select id, animal_name from AnimalData " +
213 "where id in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) " +
214 "order by id"
215 );
216 assertThat(selectStatement.getParameters()).containsEntry("p1", 5);
217 assertThat(selectStatement.getParameters()).containsEntry("p2", 6);
218
219 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
220 assertThat(rows).hasSize(2);
221
222 assertThat(rows.get(0)).containsEntry("ID", 5);
223 }
224 }
225
226 @Test
227 void testNotInWhenPresentMap() {
228 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
229 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
230
231 SelectStatementProvider selectStatement = select(id, animalName)
232 .from(animalData)
233 .where(id, isNotInWhenPresent(2, 3).map(i -> i + 3))
234 .orderBy(id)
235 .build()
236 .render(RenderingStrategies.MYBATIS3);
237
238 assertThat(selectStatement.getSelectStatement()).isEqualTo(
239 "select id, animal_name from AnimalData " +
240 "where id not in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) " +
241 "order by id"
242 );
243 assertThat(selectStatement.getParameters()).containsEntry("p1", 5);
244 assertThat(selectStatement.getParameters()).containsEntry("p2", 6);
245
246 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
247 assertThat(rows).hasSize(63);
248
249 assertThat(rows.get(0)).containsEntry("ID", 1);
250 }
251 }
252
253 @Test
254 void testInCaseInsensitiveWhenPresentMap() {
255 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
256 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
257
258 SelectStatementProvider selectStatement = select(id, animalName)
259 .from(animalData)
260 .where(animalName, isInCaseInsensitiveWhenPresent("Fred", "Betty").filter(s -> false))
261 .orderBy(id)
262 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
263 .build()
264 .render(RenderingStrategies.MYBATIS3);
265
266 assertThat(selectStatement.getSelectStatement()).isEqualTo(
267 "select id, animal_name from AnimalData " +
268 "order by id"
269 );
270
271 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
272 assertThat(rows).hasSize(65);
273
274 assertThat(rows.get(0)).containsEntry("ID", 1);
275 }
276 }
277
278 @Test
279 void testNotInCaseInsensitiveWhenPresentMap() {
280 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
281 CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class);
282
283 SelectStatementProvider selectStatement = select(id, animalName)
284 .from(animalData)
285 .where(animalName, isNotInCaseInsensitiveWhenPresent("Fred", "Betty").filter(s -> false))
286 .orderBy(id)
287 .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true))
288 .build()
289 .render(RenderingStrategies.MYBATIS3);
290
291 assertThat(selectStatement.getSelectStatement()).isEqualTo(
292 "select id, animal_name from AnimalData " +
293 "order by id"
294 );
295
296 List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
297 assertThat(rows).hasSize(65);
298
299 assertThat(rows.get(0)).containsEntry("ID", 1);
300 }
301 }
302
303 @Test
304 void testInEventuallyEmpty() {
305 var selectModel = select(id, animalName)
306 .from(animalData)
307 .where(id, isIn(1, 2).filter(s -> false))
308 .orderBy(id)
309 .build();
310
311 assertThatExceptionOfType(InvalidSqlException.class)
312 .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3))
313 .withMessage(Messages.getString("ERROR.44", "IsIn"));
314 }
315
316 @Test
317 void testInCaseInsensitiveEventuallyEmpty() {
318 var selectModel = select(id, animalName)
319 .from(animalData)
320 .where(animalName, isInCaseInsensitive("Fred", "Betty").filter(s -> false))
321 .orderBy(id)
322 .build();
323
324 assertThatExceptionOfType(InvalidSqlException.class)
325 .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3))
326 .withMessage(Messages.getString("ERROR.44", "IsInCaseInsensitive"));
327 }
328
329 @Test
330 void testNotInEventuallyEmpty() {
331 var selectModel = select(id, animalName)
332 .from(animalData)
333 .where(id, isNotIn(1, 2).filter(s -> false))
334 .orderBy(id)
335 .build();
336
337 assertThatExceptionOfType(InvalidSqlException.class)
338 .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3))
339 .withMessage(Messages.getString("ERROR.44", "IsNotIn"));
340 }
341
342 @Test
343 void testNotInCaseInsensitiveEventuallyEmpty() {
344 var selectModel = select(id, animalName)
345 .from(animalData)
346 .where(animalName, isNotInCaseInsensitive("Fred", "Betty").filter(s -> false))
347 .orderBy(id)
348 .build();
349
350 assertThatExceptionOfType(InvalidSqlException.class)
351 .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3))
352 .withMessage(Messages.getString("ERROR.44", "IsNotInCaseInsensitive"));
353 }
354
355 @Test
356 void testInEventuallyEmptyDoubleFilter() {
357 var selectModel = select(id, animalName)
358 .from(animalData)
359 .where(id, isIn(1, 2).filter(s -> false).filter(s -> false))
360 .orderBy(id)
361 .build();
362
363 assertThatExceptionOfType(InvalidSqlException.class)
364 .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3))
365 .withMessage(Messages.getString("ERROR.44", "IsIn"));
366 }
367 }