View Javadoc
1   /*
2    *    Copyright 2016-2026 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package examples.mariadb;
17  
18  import static org.assertj.core.api.Assertions.assertThat;
19  
20  import static examples.mariadb.ItemsDynamicSQLSupport.amount;
21  import static examples.mariadb.ItemsDynamicSQLSupport.id;
22  import static examples.mariadb.ItemsDynamicSQLSupport.items;
23  import static examples.mariadb.ItemsDynamicSQLSupport.description;
24  import static org.assertj.core.api.Assertions.entry;
25  import static org.mybatis.dynamic.sql.SqlBuilder.add;
26  import static org.mybatis.dynamic.sql.SqlBuilder.constant;
27  import static org.mybatis.dynamic.sql.SqlBuilder.deleteFrom;
28  import static org.mybatis.dynamic.sql.SqlBuilder.isLessThan;
29  import static org.mybatis.dynamic.sql.SqlBuilder.select;
30  import static org.mybatis.dynamic.sql.SqlBuilder.update;
31  
32  import config.TestContainersConfiguration;
33  import java.util.List;
34  import java.util.Map;
35  
36  import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
37  import org.apache.ibatis.mapping.Environment;
38  import org.apache.ibatis.session.Configuration;
39  import org.apache.ibatis.session.SqlSession;
40  import org.apache.ibatis.session.SqlSessionFactory;
41  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
42  import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
43  import org.junit.jupiter.api.BeforeAll;
44  import org.junit.jupiter.api.Test;
45  import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
46  import org.mybatis.dynamic.sql.render.RenderingStrategies;
47  import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
48  import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
49  import org.mybatis.dynamic.sql.util.mybatis3.CommonDeleteMapper;
50  import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper;
51  import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper;
52  import org.testcontainers.junit.jupiter.Container;
53  import org.testcontainers.junit.jupiter.Testcontainers;
54  import org.testcontainers.mariadb.MariaDBContainer;
55  
56  @Testcontainers
57  class MariaDBTest {
58  
59      @Container
60      private static final MariaDBContainer mariadb =
61              new MariaDBContainer(TestContainersConfiguration.MARIADB_LATEST)
62                      .withInitScript("examples/mariadb/CreateDB.sql");
63  
64      private static SqlSessionFactory sqlSessionFactory;
65  
66      @BeforeAll
67      static void setup() {
68          UnpooledDataSource ds = new UnpooledDataSource(mariadb.getDriverClassName(), mariadb.getJdbcUrl(),
69                  mariadb.getUsername(), mariadb.getPassword());
70          Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
71          Configuration config = new Configuration(environment);
72          config.addMapper(CommonDeleteMapper.class);
73          config.addMapper(CommonSelectMapper.class);
74          config.addMapper(CommonUpdateMapper.class);
75          sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
76      }
77  
78      @Test
79      void smokeTest() {
80          try (SqlSession session = sqlSessionFactory.openSession()) {
81              CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class);
82  
83              SelectStatementProvider selectStatement = select(id, description)
84                      .from(items)
85                      .orderBy(id)
86                      .build()
87                      .render(RenderingStrategies.MYBATIS3);
88               List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement);
89               assertThat(rows).hasSize(20);
90          }
91      }
92  
93      @Test
94      void testDeleteWithLimit() {
95          try (SqlSession session = sqlSessionFactory.openSession()) {
96              CommonDeleteMapper mapper = session.getMapper(CommonDeleteMapper.class);
97  
98              DeleteStatementProvider deleteStatement = deleteFrom(items)
99                      .limit(5)
100                     .build()
101                     .render(RenderingStrategies.MYBATIS3);
102 
103             assertThat(deleteStatement.getDeleteStatement())
104                     .isEqualTo("delete from items limit #{parameters.p1}");
105             assertThat(deleteStatement.getParameters()).containsOnly(entry("p1", 5L));
106 
107             int rows = mapper.delete(deleteStatement);
108             assertThat(rows).isEqualTo(5);
109         }
110     }
111 
112     @Test
113     void testDeleteWithOrderBy() {
114         try (SqlSession session = sqlSessionFactory.openSession()) {
115             CommonDeleteMapper mapper = session.getMapper(CommonDeleteMapper.class);
116 
117             DeleteStatementProvider deleteStatement = deleteFrom(items)
118                     .orderBy(amount.descending())
119                     .build()
120                     .render(RenderingStrategies.MYBATIS3);
121 
122             assertThat(deleteStatement.getDeleteStatement())
123                     .isEqualTo("delete from items order by amount DESC");
124             assertThat(deleteStatement.getParameters()).isEmpty();
125 
126             int rows = mapper.delete(deleteStatement);
127             assertThat(rows).isEqualTo(20);
128         }
129     }
130 
131     @Test
132     void testDeleteWithOrderByAndLimit() {
133         try (SqlSession session = sqlSessionFactory.openSession()) {
134             CommonDeleteMapper mapper = session.getMapper(CommonDeleteMapper.class);
135 
136             DeleteStatementProvider deleteStatement = deleteFrom(items)
137                     .orderBy(amount.descending())
138                     .limit(5)
139                     .build()
140                     .render(RenderingStrategies.MYBATIS3);
141 
142             assertThat(deleteStatement.getDeleteStatement())
143                     .isEqualTo("delete from items order by amount DESC limit #{parameters.p1}");
144             assertThat(deleteStatement.getParameters()).containsOnly(entry("p1", 5L));
145 
146             int rows = mapper.delete(deleteStatement);
147             assertThat(rows).isEqualTo(5);
148         }
149     }
150 
151     @Test
152     void testDeleteWithWhereAndLimit() {
153         try (SqlSession session = sqlSessionFactory.openSession()) {
154             CommonDeleteMapper mapper = session.getMapper(CommonDeleteMapper.class);
155 
156             DeleteStatementProvider deleteStatement = deleteFrom(items)
157                     .where(id, isLessThan(10))
158                     .limit(5)
159                     .build()
160                     .render(RenderingStrategies.MYBATIS3);
161 
162             String expected = "delete from items where id < #{parameters.p1,jdbcType=INTEGER} limit #{parameters.p2}";
163             assertThat(deleteStatement.getDeleteStatement()).isEqualTo(expected);
164             assertThat(deleteStatement.getParameters()).containsOnly(entry("p1", 10), entry("p2", 5L));
165 
166             int rows = mapper.delete(deleteStatement);
167             assertThat(rows).isEqualTo(5);
168         }
169     }
170 
171     @Test
172     void testDeleteWithWhereAndOrderBy() {
173         try (SqlSession session = sqlSessionFactory.openSession()) {
174             CommonDeleteMapper mapper = session.getMapper(CommonDeleteMapper.class);
175 
176             DeleteStatementProvider deleteStatement = deleteFrom(items)
177                     .where(id, isLessThan(10))
178                     .orderBy(amount.descending())
179                     .build()
180                     .render(RenderingStrategies.MYBATIS3);
181 
182             String expected = "delete from items where id < #{parameters.p1,jdbcType=INTEGER} order by amount DESC";
183             assertThat(deleteStatement.getDeleteStatement()).isEqualTo(expected);
184             assertThat(deleteStatement.getParameters()).containsOnly(entry("p1", 10));
185 
186             int rows = mapper.delete(deleteStatement);
187             assertThat(rows).isEqualTo(9);
188         }
189     }
190 
191     @Test
192     void testDeleteWithWhereAndOrderByAndLimit() {
193         try (SqlSession session = sqlSessionFactory.openSession()) {
194             CommonDeleteMapper mapper = session.getMapper(CommonDeleteMapper.class);
195 
196             DeleteStatementProvider deleteStatement = deleteFrom(items)
197                     .where(id, isLessThan(10))
198                     .orderBy(amount)
199                     .limit(5)
200                     .build()
201                     .render(RenderingStrategies.MYBATIS3);
202 
203             String expected = "delete from items where id < #{parameters.p1,jdbcType=INTEGER} order by amount "
204                     + "limit #{parameters.p2}";
205             assertThat(deleteStatement.getDeleteStatement()).isEqualTo(expected);
206             assertThat(deleteStatement.getParameters()).containsOnly(entry("p1", 10), entry("p2", 5L));
207 
208             int rows = mapper.delete(deleteStatement);
209             assertThat(rows).isEqualTo(5);
210         }
211     }
212 
213     @Test
214     void testUpdateWithLimit() {
215         try (SqlSession session = sqlSessionFactory.openSession()) {
216             CommonUpdateMapper mapper = session.getMapper(CommonUpdateMapper.class);
217 
218             UpdateStatementProvider updateStatement = update(items)
219                     .set(amount).equalTo(add(amount, constant("100")))
220                     .limit(5)
221                     .build()
222                     .render(RenderingStrategies.MYBATIS3);
223 
224             String expected = "update items set amount = (amount + 100) limit #{parameters.p1}";
225             assertThat(updateStatement.getUpdateStatement()).isEqualTo(expected);
226             assertThat(updateStatement.getParameters()).containsOnly(entry("p1", 5L));
227 
228             int rows = mapper.update(updateStatement);
229             assertThat(rows).isEqualTo(5);
230         }
231     }
232 
233     @Test
234     void testUpdateWithOrderBy() {
235         try (SqlSession session = sqlSessionFactory.openSession()) {
236             CommonUpdateMapper mapper = session.getMapper(CommonUpdateMapper.class);
237 
238             UpdateStatementProvider updateStatement = update(items)
239                     .set(amount).equalTo(add(amount, constant("100")))
240                     .orderBy(amount.descending())
241                     .build()
242                     .render(RenderingStrategies.MYBATIS3);
243 
244             assertThat(updateStatement.getUpdateStatement())
245                     .isEqualTo("update items set amount = (amount + 100) order by amount DESC");
246             assertThat(updateStatement.getParameters()).isEmpty();
247 
248             int rows = mapper.update(updateStatement);
249             assertThat(rows).isEqualTo(20);
250         }
251     }
252 
253     @Test
254     void testUpdateWithOrderByAndLimit() {
255         try (SqlSession session = sqlSessionFactory.openSession()) {
256             CommonUpdateMapper mapper = session.getMapper(CommonUpdateMapper.class);
257 
258             UpdateStatementProvider updateStatement = update(items)
259                     .set(amount).equalTo(add(amount, constant("100")))
260                     .orderBy(amount.descending())
261                     .limit(5)
262                     .build()
263                     .render(RenderingStrategies.MYBATIS3);
264 
265             String expected = "update items set amount = (amount + 100) order by amount DESC limit #{parameters.p1}";
266             assertThat(updateStatement.getUpdateStatement()).isEqualTo(expected);
267             assertThat(updateStatement.getParameters()).containsOnly(entry("p1", 5L));
268 
269             int rows = mapper.update(updateStatement);
270             assertThat(rows).isEqualTo(5);
271         }
272     }
273 
274     @Test
275     void testUpdateWithWhereAndLimit() {
276         try (SqlSession session = sqlSessionFactory.openSession()) {
277             CommonUpdateMapper mapper = session.getMapper(CommonUpdateMapper.class);
278 
279             UpdateStatementProvider updateStatement = update(items)
280                     .set(amount).equalTo(add(amount, constant("100")))
281                     .where(id, isLessThan(10))
282                     .limit(5)
283                     .build()
284                     .render(RenderingStrategies.MYBATIS3);
285 
286             String expected = "update items set amount = (amount + 100) where id < #{parameters.p1,jdbcType=INTEGER} "
287                     + "limit #{parameters.p2}";
288             assertThat(updateStatement.getUpdateStatement()).isEqualTo(expected);
289             assertThat(updateStatement.getParameters()).containsOnly(entry("p1", 10), entry("p2", 5L));
290 
291             int rows = mapper.update(updateStatement);
292             assertThat(rows).isEqualTo(5);
293         }
294     }
295 
296     @Test
297     void testUpdateWithWhereAndOrderBy() {
298         try (SqlSession session = sqlSessionFactory.openSession()) {
299             CommonUpdateMapper mapper = session.getMapper(CommonUpdateMapper.class);
300 
301             UpdateStatementProvider updateStatement = update(items)
302                     .set(amount).equalTo(add(amount, constant("100")))
303                     .where(id, isLessThan(10))
304                     .orderBy(amount.descending())
305                     .build()
306                     .render(RenderingStrategies.MYBATIS3);
307 
308             String expected = "update items set amount = (amount + 100) where id < #{parameters.p1,jdbcType=INTEGER} "
309                     + "order by amount DESC";
310             assertThat(updateStatement.getUpdateStatement()).isEqualTo(expected);
311             assertThat(updateStatement.getParameters()).containsOnly(entry("p1", 10));
312 
313             int rows = mapper.update(updateStatement);
314             assertThat(rows).isEqualTo(9);
315         }
316     }
317 
318     @Test
319     void testUpdateWithWhereAndOrderByAndLimit() {
320         try (SqlSession session = sqlSessionFactory.openSession()) {
321             CommonUpdateMapper mapper = session.getMapper(CommonUpdateMapper.class);
322 
323             UpdateStatementProvider updateStatement = update(items)
324                     .set(amount).equalTo(add(amount, constant("100")))
325                     .where(id, isLessThan(10))
326                     .orderBy(amount)
327                     .limit(5)
328                     .build()
329                     .render(RenderingStrategies.MYBATIS3);
330 
331             String expected = "update items set amount = (amount + 100) where id < #{parameters.p1,jdbcType=INTEGER} "
332                     + "order by amount limit #{parameters.p2}";
333             assertThat(updateStatement.getUpdateStatement()).isEqualTo(expected);
334             assertThat(updateStatement.getParameters()).containsOnly(entry("p1", 10), entry("p2", 5L));
335 
336             int rows = mapper.update(updateStatement);
337             assertThat(rows).isEqualTo(5);
338         }
339     }
340 }