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.simple;
17  
18  import static examples.simple.CompoundKeyDynamicSqlSupport.compoundKey;
19  import static examples.simple.CompoundKeyDynamicSqlSupport.id1;
20  import static examples.simple.CompoundKeyDynamicSqlSupport.id2;
21  import static org.assertj.core.api.Assertions.assertThat;
22  import static org.mybatis.dynamic.sql.SqlBuilder.insert;
23  import static org.mybatis.dynamic.sql.SqlBuilder.insertBatch;
24  import static org.mybatis.dynamic.sql.SqlBuilder.insertMultiple;
25  import static org.mybatis.dynamic.sql.SqlBuilder.select;
26  
27  import java.io.InputStream;
28  import java.io.InputStreamReader;
29  import java.sql.Connection;
30  import java.sql.DriverManager;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.function.Function;
34  import java.util.stream.IntStream;
35  
36  import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
37  import org.apache.ibatis.executor.BatchResult;
38  import org.apache.ibatis.jdbc.ScriptRunner;
39  import org.apache.ibatis.mapping.Environment;
40  import org.apache.ibatis.session.Configuration;
41  import org.apache.ibatis.session.ExecutorType;
42  import org.apache.ibatis.session.SqlSession;
43  import org.apache.ibatis.session.SqlSessionFactory;
44  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
45  import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
46  import org.junit.jupiter.api.BeforeEach;
47  import org.junit.jupiter.api.Test;
48  import org.mybatis.dynamic.sql.insert.render.BatchInsert;
49  import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider;
50  import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider;
51  import org.mybatis.dynamic.sql.render.RenderingStrategies;
52  import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
53  
54  class MyBatisMapToRowTest {
55      private static final String JDBC_URL = "jdbc:hsqldb:mem:aname";
56      private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver";
57      private SqlSessionFactory sqlSessionFactory;
58  
59      @BeforeEach
60      void setup() throws Exception {
61          Class.forName(JDBC_DRIVER);
62          try (InputStream is = getClass().getResourceAsStream("/examples/simple/CreateSimpleDB.sql")) {
63              assert is != null;
64              try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "");
65                   InputStreamReader isr = new InputStreamReader(is)) {
66                  ScriptRunner sr = new ScriptRunner(connection);
67                  sr.setLogWriter(null);
68                  sr.runScript(isr);
69              }
70          }
71  
72          UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
73          Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
74          Configuration config = new Configuration(environment);
75          config.addMapper(CompoundKeyMapper.class);
76          sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
77      }
78  
79      @Test
80      void testInsertOne() {
81          try (SqlSession session = sqlSessionFactory.openSession()) {
82              CompoundKeyMapper mapper = session.getMapper(CompoundKeyMapper.class);
83  
84              Integer i = 1;
85  
86              InsertStatementProvider<Integer> insertStatement = insert(i)
87                      .into(compoundKey)
88                      .map(id1).toConstant("22")
89                      .map(id2).toRow()
90                      .build()
91                      .render(RenderingStrategies.MYBATIS3);
92  
93              String expected = "insert into CompoundKey (id1, id2) values (22, #{row,jdbcType=INTEGER})";
94              assertThat(insertStatement.getInsertStatement()).isEqualTo(expected);
95  
96              int rows = mapper.insert(insertStatement);
97              assertThat(rows).isEqualTo(1);
98  
99              SelectStatementProvider selectStatement = select(id1, id2)
100                     .from(compoundKey)
101                     .orderBy(id1, id2)
102                     .build().render(RenderingStrategies.MYBATIS3);
103 
104             List<CompoundKeyRow> records = mapper.selectMany(selectStatement, rowMapper);
105             assertThat(records).hasSize(1);
106         }
107     }
108 
109     @Test
110     void testInsertMultiple() {
111         try (SqlSession session = sqlSessionFactory.openSession()) {
112             CompoundKeyMapper mapper = session.getMapper(CompoundKeyMapper.class);
113 
114             List<Integer> integers = List.of(1, 2, 3);
115 
116             MultiRowInsertStatementProvider<Integer> insertStatement = insertMultiple(integers)
117                     .into(compoundKey)
118                     .map(id1).toConstant("22")
119                     .map(id2).toRow()
120                     .build()
121                     .render(RenderingStrategies.MYBATIS3);
122 
123             String expected = "insert into CompoundKey (id1, id2) values (22, #{records[0],jdbcType=INTEGER}), (22, #{records[1],jdbcType=INTEGER}), (22, #{records[2],jdbcType=INTEGER})";
124             assertThat(insertStatement.getInsertStatement()).isEqualTo(expected);
125 
126             int rows = mapper.insertMultiple(insertStatement);
127             assertThat(rows).isEqualTo(3);
128 
129             SelectStatementProvider selectStatement = select(id1, id2)
130                     .from(compoundKey)
131                     .orderBy(id1, id2)
132                     .build().render(RenderingStrategies.MYBATIS3);
133 
134             List<CompoundKeyRow> records = mapper.selectMany(selectStatement, rowMapper);
135             assertThat(records).hasSize(3);
136         }
137     }
138 
139     @Test
140     void testInsertBatch() {
141         try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
142             CompoundKeyMapper mapper = session.getMapper(CompoundKeyMapper.class);
143 
144             List<Integer> integers = List.of(1, 2, 3);
145 
146             BatchInsert<Integer> insertStatement = insertBatch(integers)
147                     .into(compoundKey)
148                     .map(id1).toConstant("22")
149                     .map(id2).toRow()
150                     .build()
151                     .render(RenderingStrategies.MYBATIS3);
152 
153             String expected = "insert into CompoundKey (id1, id2) values (22, #{row,jdbcType=INTEGER})";
154             assertThat(insertStatement.getInsertStatementSQL()).isEqualTo(expected);
155 
156             insertStatement.insertStatements().forEach(mapper::insert);
157 
158             List<BatchResult> batchResults = mapper.flush();
159 
160             int rows = batchResults.stream()
161                     .map(BatchResult::getUpdateCounts)
162                     .flatMapToInt(IntStream::of)
163                     .sum();
164             assertThat(rows).isEqualTo(3);
165 
166             SelectStatementProvider selectStatement = select(id1, id2)
167                     .from(compoundKey)
168                     .orderBy(id1, id2)
169                     .build().render(RenderingStrategies.MYBATIS3);
170 
171             List<CompoundKeyRow> records = mapper.selectMany(selectStatement, rowMapper);
172             assertThat(records).hasSize(3);
173         }
174     }
175 
176     private final Function<Map<String, Object>, CompoundKeyRow> rowMapper =
177             m -> new CompoundKeyRow((Integer) m.get("ID1"), (Integer) m.get("ID2"));
178 }