Skip to content

Commit 652a821

Browse files
committed
Support for multi row inserts
1 parent cc9344b commit 652a821

18 files changed

+711
-140
lines changed

src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.mybatis.dynamic.sql.insert.BatchInsertDSL;
2525
import org.mybatis.dynamic.sql.insert.InsertDSL;
2626
import org.mybatis.dynamic.sql.insert.InsertSelectDSL;
27+
import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL;
2728
import org.mybatis.dynamic.sql.select.QueryExpressionDSL.FromGatherer;
2829
import org.mybatis.dynamic.sql.select.SelectDSL;
2930
import org.mybatis.dynamic.sql.select.SelectModel;
@@ -118,6 +119,15 @@ static <T> BatchInsertDSL.IntoGatherer<T> insert(Collection<T> records) {
118119
return BatchInsertDSL.insert(records);
119120
}
120121

122+
@SafeVarargs
123+
static <T> MultiRowInsertDSL.IntoGatherer<T> multiRowInsert(T...records) {
124+
return MultiRowInsertDSL.insert(records);
125+
}
126+
127+
static <T> MultiRowInsertDSL.IntoGatherer<T> multiRowInsert(Collection<T> records) {
128+
return MultiRowInsertDSL.insert(records);
129+
}
130+
121131
static InsertSelectDSL.InsertColumnGatherer insertInto(SqlTable table) {
122132
return InsertSelectDSL.insertInto(table);
123133
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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;
17+
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
import java.util.Collections;
21+
import java.util.List;
22+
import java.util.Objects;
23+
import java.util.function.Function;
24+
import java.util.stream.Stream;
25+
26+
import org.mybatis.dynamic.sql.SqlTable;
27+
import org.mybatis.dynamic.sql.util.InsertMapping;
28+
29+
public abstract class AbstractMultiRowInsertModel<T> {
30+
private SqlTable table;
31+
private List<T> records;
32+
private List<InsertMapping> columnMappings;
33+
34+
protected AbstractMultiRowInsertModel(AbstractBuilder<T, ?> builder) {
35+
table = Objects.requireNonNull(builder.table);
36+
records = Collections.unmodifiableList(Objects.requireNonNull(builder.records));
37+
columnMappings = Objects.requireNonNull(builder.columnMappings);
38+
}
39+
40+
public <R> Stream<R> mapColumnMappings(Function<InsertMapping, R> mapper) {
41+
return columnMappings.stream().map(mapper);
42+
}
43+
44+
public List<T> records() {
45+
return records;
46+
}
47+
48+
public SqlTable table() {
49+
return table;
50+
}
51+
52+
public int recordCount() {
53+
return records.size();
54+
}
55+
56+
public abstract static class AbstractBuilder<T, S extends AbstractBuilder<T, S>> {
57+
private SqlTable table;
58+
private List<T> records = new ArrayList<>();
59+
private List<InsertMapping> columnMappings = new ArrayList<>();
60+
61+
public S withTable(SqlTable table) {
62+
this.table = table;
63+
return getThis();
64+
}
65+
66+
public S withRecords(Collection<T> records) {
67+
this.records.addAll(records);
68+
return getThis();
69+
}
70+
71+
public S withColumnMappings(List<InsertMapping> columnMappings) {
72+
this.columnMappings.addAll(columnMappings);
73+
return getThis();
74+
}
75+
76+
protected abstract S getThis();
77+
}
78+
}

src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,43 +15,18 @@
1515
*/
1616
package org.mybatis.dynamic.sql.insert;
1717

18-
import java.util.ArrayList;
1918
import java.util.Collection;
20-
import java.util.Collections;
21-
import java.util.List;
22-
import java.util.Objects;
23-
import java.util.function.Function;
24-
import java.util.stream.Stream;
2519

26-
import org.mybatis.dynamic.sql.SqlTable;
2720
import org.mybatis.dynamic.sql.insert.render.BatchInsert;
2821
import org.mybatis.dynamic.sql.insert.render.BatchInsertRenderer;
2922
import org.mybatis.dynamic.sql.render.RenderingStrategy;
30-
import org.mybatis.dynamic.sql.util.InsertMapping;
3123

32-
public class BatchInsertModel<T> {
33-
private SqlTable table;
34-
private List<T> records;
35-
private List<InsertMapping> columnMappings;
24+
public class BatchInsertModel<T> extends AbstractMultiRowInsertModel<T> {
3625

3726
private BatchInsertModel(Builder<T> builder) {
38-
table = Objects.requireNonNull(builder.table);
39-
records = Collections.unmodifiableList(Objects.requireNonNull(builder.records));
40-
columnMappings = Objects.requireNonNull(builder.columnMappings);
27+
super(builder);
4128
}
4229

43-
public <R> Stream<R> mapColumnMappings(Function<InsertMapping, R> mapper) {
44-
return columnMappings.stream().map(mapper);
45-
}
46-
47-
public List<T> records() {
48-
return records;
49-
}
50-
51-
public SqlTable table() {
52-
return table;
53-
}
54-
5530
public BatchInsert<T> render(RenderingStrategy renderingStrategy) {
5631
return BatchInsertRenderer.withBatchInsertModel(this)
5732
.withRenderingStrategy(renderingStrategy)
@@ -63,23 +38,9 @@ public static <T> Builder<T> withRecords(Collection<T> records) {
6338
return new Builder<T>().withRecords(records);
6439
}
6540

66-
public static class Builder<T> {
67-
private SqlTable table;
68-
private List<T> records = new ArrayList<>();
69-
private List<InsertMapping> columnMappings = new ArrayList<>();
70-
71-
public Builder<T> withTable(SqlTable table) {
72-
this.table = table;
73-
return this;
74-
}
75-
76-
public Builder<T> withRecords(Collection<T> records) {
77-
this.records.addAll(records);
78-
return this;
79-
}
80-
81-
public Builder<T> withColumnMappings(List<InsertMapping> columnMappings) {
82-
this.columnMappings.addAll(columnMappings);
41+
public static class Builder<T> extends AbstractBuilder<T, Builder<T>> {
42+
@Override
43+
protected Builder<T> getThis() {
8344
return this;
8445
}
8546

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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;
17+
18+
import java.util.ArrayList;
19+
import java.util.Arrays;
20+
import java.util.Collection;
21+
import java.util.List;
22+
23+
import org.mybatis.dynamic.sql.SqlColumn;
24+
import org.mybatis.dynamic.sql.SqlTable;
25+
import org.mybatis.dynamic.sql.util.ConstantMapping;
26+
import org.mybatis.dynamic.sql.util.InsertMapping;
27+
import org.mybatis.dynamic.sql.util.NullMapping;
28+
import org.mybatis.dynamic.sql.util.PropertyMapping;
29+
import org.mybatis.dynamic.sql.util.StringConstantMapping;
30+
31+
public class MultiRowInsertDSL<T> {
32+
33+
private Collection<T> records;
34+
private SqlTable table;
35+
private List<InsertMapping> columnMappings = new ArrayList<>();
36+
37+
private MultiRowInsertDSL(Collection<T> records, SqlTable table) {
38+
this.records = records;
39+
this.table = table;
40+
}
41+
42+
public <F> ColumnMappingFinisher<F> map(SqlColumn<F> column) {
43+
return new ColumnMappingFinisher<>(column);
44+
}
45+
46+
public MultiRowInsertModel<T> build() {
47+
return MultiRowInsertModel.withRecords(records)
48+
.withTable(table)
49+
.withColumnMappings(columnMappings)
50+
.build();
51+
}
52+
53+
@SafeVarargs
54+
public static <T> IntoGatherer<T> insert(T...records) {
55+
return new IntoGatherer<>(Arrays.asList(records));
56+
}
57+
58+
public static <T> IntoGatherer<T> insert(Collection<T> records) {
59+
return new IntoGatherer<>(records);
60+
}
61+
62+
public static class IntoGatherer<T> {
63+
private Collection<T> records;
64+
65+
private IntoGatherer(Collection<T> records) {
66+
this.records = records;
67+
}
68+
69+
public MultiRowInsertDSL<T> into(SqlTable table) {
70+
return new MultiRowInsertDSL<>(records, table);
71+
}
72+
}
73+
74+
public class ColumnMappingFinisher<F> {
75+
private SqlColumn<F> column;
76+
77+
public ColumnMappingFinisher(SqlColumn<F> column) {
78+
this.column = column;
79+
}
80+
81+
public MultiRowInsertDSL<T> toProperty(String property) {
82+
columnMappings.add(PropertyMapping.of(column, property));
83+
return MultiRowInsertDSL.this;
84+
}
85+
86+
public MultiRowInsertDSL<T> toNull() {
87+
columnMappings.add(NullMapping.of(column));
88+
return MultiRowInsertDSL.this;
89+
}
90+
91+
public MultiRowInsertDSL<T> toConstant(String constant) {
92+
columnMappings.add(ConstantMapping.of(column, constant));
93+
return MultiRowInsertDSL.this;
94+
}
95+
96+
public MultiRowInsertDSL<T> toStringConstant(String constant) {
97+
columnMappings.add(StringConstantMapping.of(column, constant));
98+
return MultiRowInsertDSL.this;
99+
}
100+
}
101+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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;
17+
18+
import java.util.Collection;
19+
20+
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertRenderer;
21+
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider;
22+
import org.mybatis.dynamic.sql.render.RenderingStrategy;
23+
24+
public class MultiRowInsertModel<T> extends AbstractMultiRowInsertModel<T> {
25+
26+
private MultiRowInsertModel(Builder<T> builder) {
27+
super(builder);
28+
}
29+
30+
public MultiRowInsertStatementProvider<T> render(RenderingStrategy renderingStrategy) {
31+
return MultiRowInsertRenderer.withMultiRowInsertModel(this)
32+
.withRenderingStrategy(renderingStrategy)
33+
.build()
34+
.render();
35+
}
36+
37+
public static <T> Builder<T> withRecords(Collection<T> records) {
38+
return new Builder<T>().withRecords(records);
39+
}
40+
41+
public static class Builder<T> extends AbstractBuilder<T, Builder<T>> {
42+
@Override
43+
protected Builder<T> getThis() {
44+
return this;
45+
}
46+
47+
public MultiRowInsertModel<T> build() {
48+
return new MultiRowInsertModel<>(this);
49+
}
50+
}
51+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private BatchInsertRenderer(Builder<T> builder) {
3636

3737
public BatchInsert<T> render() {
3838
ValuePhraseVisitor visitor = new ValuePhraseVisitor(renderingStrategy);
39-
FieldAndValueCollector<T> collector = model.mapColumnMappings(toFieldAndValue(visitor))
39+
FieldAndValueCollector collector = model.mapColumnMappings(toFieldAndValue(visitor))
4040
.collect(FieldAndValueCollector.collect());
4141

4242
return BatchInsert.withRecords(model.records())
@@ -52,7 +52,7 @@ private FieldAndValue toFieldAndValue(ValuePhraseVisitor visitor, InsertMapping
5252
return insertMapping.accept(visitor);
5353
}
5454

55-
private String calculateInsertStatement(FieldAndValueCollector<T> collector) {
55+
private String calculateInsertStatement(FieldAndValueCollector collector) {
5656
return "insert into" //$NON-NLS-1$
5757
+ spaceBefore(model.table().tableNameAtRuntime())
5858
+ spaceBefore(collector.columnsPhrase())

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