Skip to content

Commit cc9344b

Browse files
committed
Provider objects and test for multi-row inserts
1 parent 9e7a99b commit cc9344b

File tree

6 files changed

+142
-48
lines changed

6 files changed

+142
-48
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright 2016-2019 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+
* http://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 org.mybatis.dynamic.sql.insert.render;
17+
18+
import java.util.ArrayList;
19+
import java.util.Collections;
20+
import java.util.List;
21+
import java.util.Objects;
22+
23+
public class DefaultMultiRowInsertStatementProvider<T> implements MultiRowInsertStatementProvider<T> {
24+
25+
private List<T> records;
26+
private String insertStatement;
27+
28+
private DefaultMultiRowInsertStatementProvider(Builder<T> builder) {
29+
insertStatement = Objects.requireNonNull(builder.insertStatement);
30+
records = Collections.unmodifiableList(builder.records);
31+
}
32+
33+
@Override
34+
public String getInsertStatement() {
35+
return insertStatement;
36+
}
37+
38+
@Override
39+
public List<T> getRecords() {
40+
return records;
41+
}
42+
43+
public static class Builder<T> {
44+
private List<T> records = new ArrayList<>();
45+
private String insertStatement;
46+
47+
public Builder<T> withRecords(List<T> records) {
48+
this.records.addAll(records);
49+
return this;
50+
}
51+
52+
public Builder<T> withInsertStatement(String insertStatement) {
53+
this.insertStatement = insertStatement;
54+
return this;
55+
}
56+
57+
public DefaultMultiRowInsertStatementProvider<T> build() {
58+
return new DefaultMultiRowInsertStatementProvider<>(this);
59+
}
60+
}
61+
}

src/main/java/org/mybatis/dynamic/sql/insert/render/MultiInsertStatementProvider.java

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright 2016-2019 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+
* http://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 org.mybatis.dynamic.sql.insert.render;
17+
18+
import java.util.List;
19+
20+
public interface MultiRowInsertStatementProvider<T> {
21+
22+
String getInsertStatement();
23+
24+
List<T> getRecords();
25+
}

src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2017 the original author or authors.
2+
* Copyright 2016-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,10 +15,11 @@
1515
*/
1616
package org.mybatis.dynamic.sql.util;
1717

18+
import java.util.Map;
19+
1820
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
1921
import org.mybatis.dynamic.sql.insert.render.InsertSelectStatementProvider;
2022
import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider;
21-
import org.mybatis.dynamic.sql.insert.render.MultiInsertStatementProvider;
2223
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
2324
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
2425

@@ -38,8 +39,8 @@ public String insert(InsertStatementProvider<?> insertStatement) {
3839
return insertStatement.getInsertStatement();
3940
}
4041

41-
public String multiInsert(MultiInsertStatementProvider insertStatement) {
42-
return insertStatement.getInsertStatement();
42+
public String multiInsert(Map<String, Object> parameter) {
43+
return (String) parameter.get("statement"); //$NON-NLS-1$
4344
}
4445

4546
public String insertSelect(InsertSelectStatementProvider insertStatement) {

src/test/java/examples/generated/always/mybatis/GeneratedAlwaysAnnotatedMapper.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2017 the original author or authors.
2+
* Copyright 2016-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,13 +19,14 @@
1919

2020
import org.apache.ibatis.annotations.InsertProvider;
2121
import org.apache.ibatis.annotations.Options;
22+
import org.apache.ibatis.annotations.Param;
2223
import org.apache.ibatis.annotations.Result;
2324
import org.apache.ibatis.annotations.ResultMap;
2425
import org.apache.ibatis.annotations.Results;
2526
import org.apache.ibatis.annotations.SelectProvider;
2627
import org.apache.ibatis.annotations.UpdateProvider;
2728
import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider;
28-
import org.mybatis.dynamic.sql.insert.render.MultiInsertStatementProvider;
29+
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider;
2930
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
3031
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
3132
import org.mybatis.dynamic.sql.util.SqlProviderAdapter;
@@ -50,10 +51,17 @@ public interface GeneratedAlwaysAnnotatedMapper {
5051
@Options(useGeneratedKeys=true, keyProperty="record.fullName")
5152
int insert(InsertStatementProvider<GeneratedAlwaysRecord> insertStatement);
5253

53-
@InsertProvider(type=SqlProviderAdapter.class, method="multiInsert")
54-
@Options(useGeneratedKeys=true, keyProperty="fullName")
55-
int multiInsert(MultiInsertStatementProvider multiInsert);
56-
5754
@UpdateProvider(type=SqlProviderAdapter.class, method="update")
5855
int update(UpdateStatementProvider updateStatement);
56+
57+
@InsertProvider(type=SqlProviderAdapter.class, method="multiInsert")
58+
@Options(useGeneratedKeys=true, keyProperty="records.fullName")
59+
int multiInsert(@Param("statement") String statement, @Param("records") List<GeneratedAlwaysRecord> records);
60+
61+
// TODO - this is kludgy. Currently MyBatis does not support nested lists in parameter objects,
62+
// so we need to do this silliness and decompose the multi insert into its component parts
63+
// for the actual MyBatis call
64+
default int multiInsert(MultiRowInsertStatementProvider<GeneratedAlwaysRecord> multiInsert) {
65+
return multiInsert(multiInsert.getInsertStatement(), multiInsert.getRecords());
66+
}
5967
}

src/test/java/examples/generated/always/mybatis/GeneratedAlwaysAnnotatedMapperTest.java

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2018 the original author or authors.
2+
* Copyright 2016-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,7 +51,8 @@
5151
import org.junit.jupiter.api.BeforeEach;
5252
import org.junit.jupiter.api.Test;
5353
import org.mybatis.dynamic.sql.insert.render.BatchInsert;
54-
import org.mybatis.dynamic.sql.insert.render.MultiInsertStatementProvider;
54+
import org.mybatis.dynamic.sql.insert.render.DefaultMultiRowInsertStatementProvider;
55+
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider;
5556
import org.mybatis.dynamic.sql.render.RenderingStrategy;
5657
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
5758
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
@@ -193,6 +194,31 @@ public void testBatchInsertWithArray() {
193194
}
194195
}
195196

197+
@Test
198+
public void testMultiInsertWithRawMyBatisAnnotations() {
199+
try (SqlSession session = sqlSessionFactory.openSession()) {
200+
GeneratedAlwaysAnnotatedMapper mapper = session.getMapper(GeneratedAlwaysAnnotatedMapper.class);
201+
List<GeneratedAlwaysRecord> records = getTestRecords();
202+
203+
String statement = "insert into GeneratedAlways (id, first_name, last_name)" +
204+
" values" +
205+
" (#{records[0].id,jdbcType=INTEGER}, #{records[0].firstName,jdbcType=VARCHAR}, #{records[0].lastName,jdbcType=VARCHAR})," +
206+
" (#{records[1].id,jdbcType=INTEGER}, #{records[1].firstName,jdbcType=VARCHAR}, #{records[1].lastName,jdbcType=VARCHAR})," +
207+
" (#{records[2].id,jdbcType=INTEGER}, #{records[2].firstName,jdbcType=VARCHAR}, #{records[2].lastName,jdbcType=VARCHAR})," +
208+
" (#{records[3].id,jdbcType=INTEGER}, #{records[3].firstName,jdbcType=VARCHAR}, #{records[3].lastName,jdbcType=VARCHAR})";
209+
210+
int rows = mapper.multiInsert(statement, records);
211+
212+
assertAll(
213+
() -> assertThat(rows).isEqualTo(4),
214+
() -> assertThat(records.get(0).getFullName()).isEqualTo("George Jetson"),
215+
() -> assertThat(records.get(1).getFullName()).isEqualTo("Jane Jetson"),
216+
() -> assertThat(records.get(2).getFullName()).isEqualTo("Judy Jetson"),
217+
() -> assertThat(records.get(3).getFullName()).isEqualTo("Elroy Jetson")
218+
);
219+
}
220+
}
221+
196222
@Test
197223
public void testMultiInsertWithList() {
198224
try (SqlSession session = sqlSessionFactory.openSession()) {
@@ -207,18 +233,18 @@ public void testMultiInsertWithList() {
207233
// .build()
208234
// .render(RenderingStrategy.MYBATIS3);
209235

210-
MultiInsertStatementProvider insertStatement = new MultiInsertStatementProvider();
211-
212236
String statement = "insert into GeneratedAlways (id, first_name, last_name)" +
213-
" values (#{list[0].id,jdbcType=INTEGER}, #{list[0].firstName,jdbcType=VARCHAR}, #{list[0].lastName,jdbcType=VARCHAR})," +
214-
" (#{list[1].id,jdbcType=INTEGER}, #{list[1].firstName,jdbcType=VARCHAR}, #{list[1].lastName,jdbcType=VARCHAR})," +
215-
" (#{list[2].id,jdbcType=INTEGER}, #{list[2].firstName,jdbcType=VARCHAR}, #{list[2].lastName,jdbcType=VARCHAR})," +
216-
" (#{list[3].id,jdbcType=INTEGER}, #{list[3].firstName,jdbcType=VARCHAR}, #{list[3].lastName,jdbcType=VARCHAR})";
237+
" values" +
238+
" (#{records[0].id,jdbcType=INTEGER}, #{records[0].firstName,jdbcType=VARCHAR}, #{records[0].lastName,jdbcType=VARCHAR})," +
239+
" (#{records[1].id,jdbcType=INTEGER}, #{records[1].firstName,jdbcType=VARCHAR}, #{records[1].lastName,jdbcType=VARCHAR})," +
240+
" (#{records[2].id,jdbcType=INTEGER}, #{records[2].firstName,jdbcType=VARCHAR}, #{records[2].lastName,jdbcType=VARCHAR})," +
241+
" (#{records[3].id,jdbcType=INTEGER}, #{records[3].firstName,jdbcType=VARCHAR}, #{records[3].lastName,jdbcType=VARCHAR})";
217242

218-
insertStatement.setInsertStatement(statement);
219-
insertStatement.setList(records);
243+
MultiRowInsertStatementProvider<GeneratedAlwaysRecord> insertStatement = new DefaultMultiRowInsertStatementProvider.Builder<GeneratedAlwaysRecord>()
244+
.withInsertStatement(statement)
245+
.withRecords(records)
246+
.build();
220247

221-
// must use a Map...MyBatis is broken for using real objects
222248
mapper.multiInsert(insertStatement);
223249

224250
assertAll(

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy