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