Skip to content

Commit 8185164

Browse files
committed
Merge branch 'master' into map-to-row
# Conflicts: # src/main/java/org/mybatis/dynamic/sql/insert/render/AbstractMultiRowValuePhraseVisitor.java # src/main/java/org/mybatis/dynamic/sql/insert/render/BatchValuePhraseVisitor.java # src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java
2 parents 90e12af + 2aa431a commit 8185164

File tree

13 files changed

+110
-67
lines changed

13 files changed

+110
-67
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@
287287
<dependency>
288288
<groupId>ch.qos.logback</groupId>
289289
<artifactId>logback-classic</artifactId>
290-
<version>1.4.6</version>
290+
<version>1.4.7</version>
291291
<scope>test</scope>
292292
</dependency>
293293
<!-- Hamcrest is only here to make Infinitest happy. Not really used in the project. -->

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,16 @@ public FieldAndValueAndParameters visit(PropertyMapping mapping) {
6464
.build();
6565
}
6666

67+
private String calculateJdbcPlaceholder(SqlColumn<?> column, String parameterName) {
68+
return column.renderingStrategy().orElse(renderingStrategy)
69+
.getRecordBasedInsertBinding(column, prefix, parameterName);
70+
}
6771
@Override
6872
public FieldAndValueAndParameters visit(RowMapping mapping) {
6973
return FieldAndValueAndParameters.withFieldName(mapping.columnName())
7074
.withValuePhrase(mapping.mapColumn(this::calculateJdbcPlaceholder))
7175
.build();
7276
}
7377

74-
abstract String calculateJdbcPlaceholder(SqlColumn<?> column, String parameterName);
75-
7678
abstract String calculateJdbcPlaceholder(SqlColumn<?> column);
7779
}

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ public BatchValuePhraseVisitor(RenderingStrategy renderingStrategy, String prefi
2424
super(renderingStrategy, prefix);
2525
}
2626

27-
@Override
28-
String calculateJdbcPlaceholder(SqlColumn<?> column, String parameterName) {
29-
return column.renderingStrategy().orElse(renderingStrategy)
30-
.getFormattedJdbcPlaceholder(column, prefix, parameterName);
31-
}
32-
3327
@Override
3428
String calculateJdbcPlaceholder(SqlColumn<?> column) {
3529
return column.renderingStrategy().orElse(renderingStrategy).getFormattedJdbcPlaceholder(column, prefix);

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ public MultiRowValuePhraseVisitor(RenderingStrategy renderingStrategy, String pr
2424
super(renderingStrategy, prefix);
2525
}
2626

27-
@Override
28-
String calculateJdbcPlaceholder(SqlColumn<?> column, String parameterName) {
29-
return column.renderingStrategy().orElse(renderingStrategy)
30-
.getMultiRowFormattedJdbcPlaceholder(column, prefix, parameterName);
31-
}
32-
3327
@Override
3428
String calculateJdbcPlaceholder(SqlColumn<?> column) {
3529
return column.renderingStrategy().orElse(renderingStrategy).getMultiRowFormattedJdbcPlaceholder(column, prefix);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ public Optional<FieldAndValueAndParameters> visit(PropertyWhenPresentMapping map
7575

7676
private String calculateJdbcPlaceholder(SqlColumn<?> column, String parameterName) {
7777
return column.renderingStrategy().orElse(renderingStrategy)
78-
.getFormattedJdbcPlaceholder(column, "row", parameterName); //$NON-NLS-1$
78+
.getRecordBasedInsertBinding(column, "row", parameterName); //$NON-NLS-1$
7979
}
8080
}

src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121

2222
/**
2323
* A rendering strategy is used to generate a platform specific binding.
24-
* <p>
25-
* Rendering strategies are used during the rendering phase of statement generation.
24+
*
25+
* <p>Rendering strategies are used during the rendering phase of statement generation.
2626
* All generated SQL statements include the generated statement itself, and a map of parameters that
2727
* should be bound to the statement at execution time. For example, a generated select statement may
2828
* look like this when rendered for MyBatis:
29-
* <p>
30-
* <code>select foo from bar where id = #{parameters.p1,jdbcType=INTEGER}</code>
31-
* <p>
32-
* In this case, the binding is <code>#{parameters.p1,jdbcType=INTEGER}</code>. MyBatis knows how to interpret this
29+
*
30+
* <p><code>select foo from bar where id = #{parameters.p1,jdbcType=INTEGER}</code>
31+
*
32+
* <p>In this case, the binding is <code>#{parameters.p1,jdbcType=INTEGER}</code>. MyBatis knows how to interpret this
3333
* binding - it will look for a value in the <code>parameters.p1</code> property of the parameter object
3434
* passed to the statement and bind it as a prepared statement parameter when executing the statement.
3535
*/
@@ -42,61 +42,62 @@ public String formatParameterMapKey(AtomicInteger sequence) {
4242

4343
/**
4444
* This method generates a binding for a parameter to a placeholder in a generated SQL statement.
45-
* <p>
46-
* This binding is appropriate when there can be a mapping between a parameter and a known target column,
45+
*
46+
* <p>This binding is appropriate when there can be a mapping between a parameter and a known target column,
4747
* In MyBatis, the binding can specify type information based on the column. The bindings are specific
4848
* to the target framework.
49-
* <p>
50-
* For MyBatis, a binding looks like this: "#{prefix.parameterName,jdbcType=xxx,typeHandler=xxx,javaType=xxx}"
51-
* <p>
52-
* For Spring, a binding looks like this: ":parameterName"
49+
*
50+
* <p>For MyBatis, a binding looks like this: "#{prefix.parameterName,jdbcType=xxx,typeHandler=xxx,javaType=xxx}"
51+
*
52+
* <p>For Spring, a binding looks like this: ":parameterName"
5353
*
5454
* @param column column definition used for generating type details in a MyBatis binding. Ignored for Spring.
5555
* @param prefix parameter prefix used for locating the parameters in a SQL provider object. Typically, will be
5656
* {@link RenderingStrategy#DEFAULT_PARAMETER_PREFIX}. This is ignored for Spring.
5757
* @param parameterName name of the parameter. Typically generated by calling
58-
* {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)}
58+
* {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)}
5959
* @return the generated binding
6060
*/
6161
public abstract String getFormattedJdbcPlaceholder(BindableColumn<?> column, String prefix, String parameterName);
6262

6363
/**
6464
* This method generates a binding for a parameter to a placeholder in a generated SQL statement.
65-
* <p>
66-
* This binding is appropriate when the parameter is bound to placeholder that is not a known column (such as
65+
*
66+
* <p>This binding is appropriate when the parameter is bound to placeholder that is not a known column (such as
6767
* a limit or offset parameter). The bindings are specific to the target framework.
68-
* <p>
69-
* For MyBatis, a binding looks like this: "#{prefix.parameterName}"
70-
* <p>
71-
* For Spring, a binding looks like this: ":parameterName"
68+
*
69+
* <p>For MyBatis, a binding looks like this: "#{prefix.parameterName}"
70+
*
71+
* <p>For Spring, a binding looks like this: ":parameterName"
7272
*
7373
* @param prefix parameter prefix used for locating the parameters in a SQL provider object. Typically, will be
7474
* {@link RenderingStrategy#DEFAULT_PARAMETER_PREFIX}. This is ignored for Spring.
7575
* @param parameterName name of the parameter. Typically generated by calling
76-
* {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)}
76+
* {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)}
7777
* @return the generated binding
7878
*/
7979
public abstract String getFormattedJdbcPlaceholder(String prefix, String parameterName);
8080

8181
/**
82-
* This method generates a binding for a parameter to a placeholder in a generated multirow insert statement.
83-
* <p>
84-
* This binding is specifically for use with a multirow insert. The Spring implementation changes the binding
85-
* to match values expected for a multirow insert statement. For MyBatis, the binding is the same
82+
* This method generates a binding for a parameter to a placeholder in a record based insert statement.
83+
*
84+
* <p>This binding is specifically for use with insert, batch insert, and multirow insert statements.
85+
* These statements bind parameters to properties of a row class. The Spring implementation changes the binding
86+
* to match values expected for a these insert statements. For MyBatis, the binding is the same
8687
* as {@link RenderingStrategy#getFormattedJdbcPlaceholder(BindableColumn, String, String)}.
87-
* <p>
88-
* For MyBatis, a binding looks like this: "#{prefix.parameterName,jdbcType=xxx,typeHandler=xxx,javaType=xxx}"
89-
* <p>
90-
* For Spring, a binding looks like this: ":prefix.parameterName"
88+
*
89+
* <p>For MyBatis, a binding looks like this: "#{prefix.parameterName,jdbcType=xxx,typeHandler=xxx,javaType=xxx}"
90+
*
91+
* <p>For Spring, a binding looks like this: ":prefix.parameterName"
9192
*
9293
* @param column column definition used for generating type details in a MyBatis binding. Ignored for Spring.
9394
* @param prefix parameter prefix used for locating the parameters in a SQL provider object. Typically, will be
94-
* {@link RenderingStrategy#DEFAULT_PARAMETER_PREFIX}. This is ignored for Spring.
95+
* {@link RenderingStrategy#DEFAULT_PARAMETER_PREFIX}. This is ignored for Spring.
9596
* @param parameterName name of the parameter. Typically generated by calling
96-
* {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)}
97+
* {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)}
9798
* @return the generated binding
9899
*/
99-
public String getMultiRowFormattedJdbcPlaceholder(BindableColumn<?> column, String prefix, String parameterName) {
100+
public String getRecordBasedInsertBinding(BindableColumn<?> column, String prefix, String parameterName) {
100101
return getFormattedJdbcPlaceholder(column, prefix, parameterName);
101102
}
102103

src/main/java/org/mybatis/dynamic/sql/render/SpringNamedParameterRenderingStrategy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public String getFormattedJdbcPlaceholder(String prefix, String parameterName) {
3535
}
3636

3737
@Override
38-
public String getMultiRowFormattedJdbcPlaceholder(BindableColumn<?> column, String prefix, String parameterName) {
38+
public String getRecordBasedInsertBinding(BindableColumn<?> column, String prefix, String parameterName) {
3939
return ":" + prefix + "." + parameterName; //$NON-NLS-1$ //$NON-NLS-2$
4040
}
4141

src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
*/
1616
package org.mybatis.dynamic.sql.select;
1717

18+
import java.util.List;
19+
1820
import org.mybatis.dynamic.sql.AndOrCriteriaGroup;
1921
import org.mybatis.dynamic.sql.SqlCriterion;
2022
import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionDSL;
2123

22-
import java.util.List;
23-
2424
public abstract class AbstractHavingFinisher<T extends AbstractHavingFinisher<T>>
2525
extends AbstractBooleanExpressionDSL<T> {
2626
void initialize(SqlCriterion sqlCriterion) {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2016-2023 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 org.mybatis.dynamic.sql.util.spring;
17+
18+
import java.util.List;
19+
import java.util.stream.Collectors;
20+
21+
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
22+
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
23+
24+
/**
25+
* Utility class for converting a list of rows to an array or SqlParameterSources.
26+
*
27+
* <p>This class is necessary due to the way that the library generates bindings for batch insert
28+
* statements. The bindings will be of the form <code>:row.propertyName</code>. The <code>createBatch</code> method
29+
* in this class will wrap all input rows in a class - RowHolder - with a single property named "row".
30+
* This will allow the generated bindings to function properly with a Spring batch insert.
31+
*/
32+
public class BatchInsertUtility {
33+
private BatchInsertUtility() {}
34+
35+
public static <T> SqlParameterSource[] createBatch(List<T> rows) {
36+
List<RowHolder<T>> tt = rows.stream()
37+
.map(RowHolder::new)
38+
.collect(Collectors.toList());
39+
40+
return SqlParameterSourceUtils.createBatch(tt);
41+
}
42+
43+
public static class RowHolder<T> {
44+
private final T row;
45+
46+
public RowHolder(T row) {
47+
this.row = row;
48+
}
49+
50+
public T getRow() {
51+
return row;
52+
}
53+
}
54+
}

src/main/java/org/mybatis/dynamic/sql/util/spring/NamedParameterJdbcTemplateExtensions.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
4242
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
4343
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
44-
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
45-
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
4644
import org.springframework.jdbc.support.KeyHolder;
4745

4846
public class NamedParameterJdbcTemplateExtensions {
@@ -91,7 +89,7 @@ public <T> int insert(Buildable<InsertModel<T>> insertStatement) {
9189

9290
public <T> int insert(InsertStatementProvider<T> insertStatement) {
9391
return template.update(insertStatement.getInsertStatement(),
94-
new BeanPropertySqlParameterSource(insertStatement.getRow()));
92+
new BeanPropertySqlParameterSource(insertStatement));
9593
}
9694

9795
public <T> int insert(Buildable<InsertModel<T>> insertStatement, KeyHolder keyHolder) {
@@ -100,16 +98,16 @@ public <T> int insert(Buildable<InsertModel<T>> insertStatement, KeyHolder keyHo
10098

10199
public <T> int insert(InsertStatementProvider<T> insertStatement, KeyHolder keyHolder) {
102100
return template.update(insertStatement.getInsertStatement(),
103-
new BeanPropertySqlParameterSource(insertStatement.getRow()), keyHolder);
101+
new BeanPropertySqlParameterSource(insertStatement), keyHolder);
104102
}
105103

106104
public <T> int[] insertBatch(Buildable<BatchInsertModel<T>> insertStatement) {
107105
return insertBatch(insertStatement.build().render(RenderingStrategies.SPRING_NAMED_PARAMETER));
108106
}
109107

110108
public <T> int[] insertBatch(BatchInsert<T> insertStatement) {
111-
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(insertStatement.getRecords());
112-
return template.batchUpdate(insertStatement.getInsertStatementSQL(), batch);
109+
return template.batchUpdate(insertStatement.getInsertStatementSQL(),
110+
BatchInsertUtility.createBatch(insertStatement.getRecords()));
113111
}
114112

115113
public <T> int insertMultiple(Buildable<MultiRowInsertModel<T>> insertStatement) {

0 commit comments

Comments
 (0)