From 368a79855b1781337fb3da9145cbef3932d2d3c7 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 16 Jul 2025 00:14:24 +0000
Subject: [PATCH 01/68] Update dependency maven to v3.9.11
---
.mvn/wrapper/maven-wrapper.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 0d35f6dbb..b06697c61 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -16,5 +16,5 @@
# under the License.
wrapperVersion=3.3.2
distributionType=source
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
From 9e614ffe2a4e866cfcb210a292f3e6d3b75f556f Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 17 Jul 2025 11:13:20 +0000
Subject: [PATCH 02/68] Update dependency org.springframework:spring-jdbc to
v6.2.9
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 9e41feb33..1e8cd801d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,7 +103,7 @@
org.springframework
spring-jdbc
- 6.2.8
+ 6.2.9
provided
true
From 88dece895d4d25f0ebc6fdebf8ebc5733942cd0e Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 21 Jul 2025 10:58:02 +0000
Subject: [PATCH 03/68] Update junit-framework monorepo to v5.13.4
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 1e8cd801d..7c2cdb32c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,7 +60,7 @@
17
17
17
- 5.13.3
+ 5.13.4
5.2.2
checkstyle-override.xml
From 95f3fa98546719e047ac6c6117cfa415e9eb73ab Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Fri, 25 Jul 2025 16:54:38 -0400
Subject: [PATCH 04/68] Support "mappedColumn" on insert statements
We added a "javaProperty" to SqlColumn so properties can be centrally configured, and then used on generated insert statements.
This will make the mappers generated from MyBatis Generator less verbose.
---
.../org/mybatis/dynamic/sql/SqlColumn.java | 20 +++++-
.../mybatis/dynamic/sql/insert/InsertDSL.java | 12 ++++
.../dynamic/sql/insert/MultiRowInsertDSL.java | 6 ++
.../render/MultiRowValuePhraseVisitor.java | 19 ++++++
.../sql/insert/render/ValuePhraseVisitor.java | 29 +++++++++
.../sql/util/ColumnMappingVisitor.java | 4 ++
.../sql/util/GeneralInsertMappingVisitor.java | 10 +++
.../dynamic/sql/util/InternalError.java | 7 +-
.../dynamic/sql/util/MappedColumnMapping.java | 34 ++++++++++
.../util/MappedColumnWhenPresentMapping.java | 43 +++++++++++++
.../util/MultiRowInsertMappingVisitor.java | 5 ++
.../sql/util/UpdateMappingVisitor.java | 10 +++
.../dynamic/sql/util/messages.properties | 1 +
.../simple/PersonDynamicSqlSupport.java | 22 +++++--
.../java/examples/simple/PersonMapper.java | 42 ++++++------
.../examples/spring/PersonTemplateTest.java | 5 +-
.../sql/insert/render/InsertVisitorsTest.java | 60 +++++++++++++++++
.../sql/util/ColumnMappingVisitorTest.java | 64 +++++++++++++++++++
18 files changed, 360 insertions(+), 33 deletions(-)
create mode 100644 src/main/java/org/mybatis/dynamic/sql/util/MappedColumnMapping.java
create mode 100644 src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/insert/render/InsertVisitorsTest.java
diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java
index 4c841d86b..0d3a9ec44 100644
--- a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java
+++ b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java
@@ -37,6 +37,7 @@ public class SqlColumn implements BindableColumn, SortSpecification {
protected final ParameterTypeConverter parameterTypeConverter;
protected final @Nullable String tableQualifier;
protected final @Nullable Class javaType;
+ protected final @Nullable String javaProperty;
private SqlColumn(Builder builder) {
name = Objects.requireNonNull(builder.name);
@@ -49,6 +50,7 @@ private SqlColumn(Builder builder) {
parameterTypeConverter = Objects.requireNonNull(builder.parameterTypeConverter);
tableQualifier = builder.tableQualifier;
javaType = builder.javaType;
+ javaProperty = builder.javaProperty;
}
public String name() {
@@ -79,6 +81,10 @@ public Optional> javaType() {
return Optional.ofNullable(javaType);
}
+ public Optional javaProperty() {
+ return Optional.ofNullable(javaProperty);
+ }
+
@Override
public @Nullable Object convertParameterType(@Nullable T value) {
return value == null ? null : parameterTypeConverter.convert(value);
@@ -164,6 +170,11 @@ public SqlColumn withJavaType(Class javaType) {
return b.withJavaType(javaType).build();
}
+ public SqlColumn withJavaProperty(String javaProperty) {
+ Builder b = copy();
+ return b.withJavaProperty(javaProperty).build();
+ }
+
/**
* This method helps us tell a bit of fiction to the Java compiler. Java, for better or worse,
* does not carry generic type information through chained methods. We want to enable method
@@ -185,7 +196,8 @@ private Builder copy() {
.withRenderingStrategy(this.renderingStrategy)
.withParameterTypeConverter((ParameterTypeConverter) this.parameterTypeConverter)
.withTableQualifier(this.tableQualifier)
- .withJavaType((Class) this.javaType);
+ .withJavaType((Class) this.javaType)
+ .withJavaProperty(this.javaProperty);
}
public static SqlColumn of(String name, SqlTable table) {
@@ -212,6 +224,7 @@ public static class Builder {
protected ParameterTypeConverter parameterTypeConverter = v -> v;
protected @Nullable String tableQualifier;
protected @Nullable Class javaType;
+ protected @Nullable String javaProperty;
public Builder withName(String name) {
this.name = name;
@@ -263,6 +276,11 @@ public Builder withJavaType(@Nullable Class javaType) {
return this;
}
+ public Builder withJavaProperty(@Nullable String javaProperty) {
+ this.javaProperty = javaProperty;
+ return this;
+ }
+
public SqlColumn build() {
return new SqlColumn<>(this);
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java
index d622ced8c..8b95a9c0f 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java
@@ -27,6 +27,8 @@
import org.mybatis.dynamic.sql.util.AbstractColumnMapping;
import org.mybatis.dynamic.sql.util.Buildable;
import org.mybatis.dynamic.sql.util.ConstantMapping;
+import org.mybatis.dynamic.sql.util.MappedColumnMapping;
+import org.mybatis.dynamic.sql.util.MappedColumnWhenPresentMapping;
import org.mybatis.dynamic.sql.util.NullMapping;
import org.mybatis.dynamic.sql.util.PropertyMapping;
import org.mybatis.dynamic.sql.util.PropertyWhenPresentMapping;
@@ -49,6 +51,16 @@ public ColumnMappingFinisher map(SqlColumn column) {
return new ColumnMappingFinisher<>(column);
}
+ public InsertDSL withMappedColumn(SqlColumn column) {
+ columnMappings.add(MappedColumnMapping.of(column));
+ return this;
+ }
+
+ public InsertDSL withMappedColumnWhenPresent(SqlColumn column, Supplier> valueSupplier) {
+ columnMappings.add(MappedColumnWhenPresentMapping.of(column, valueSupplier));
+ return this;
+ }
+
@Override
public InsertModel build() {
return InsertModel.withRow(row)
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java
index 8e5f30e49..87705c415 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java
@@ -25,6 +25,7 @@
import org.mybatis.dynamic.sql.util.AbstractColumnMapping;
import org.mybatis.dynamic.sql.util.Buildable;
import org.mybatis.dynamic.sql.util.ConstantMapping;
+import org.mybatis.dynamic.sql.util.MappedColumnMapping;
import org.mybatis.dynamic.sql.util.NullMapping;
import org.mybatis.dynamic.sql.util.PropertyMapping;
import org.mybatis.dynamic.sql.util.RowMapping;
@@ -46,6 +47,11 @@ public ColumnMappingFinisher map(SqlColumn column) {
return new ColumnMappingFinisher<>(column);
}
+ public MultiRowInsertDSL withMappedColumn(SqlColumn column) {
+ columnMappings.add(MappedColumnMapping.of(column));
+ return this;
+ }
+
@Override
public MultiRowInsertModel build() {
return MultiRowInsertModel.withRecords(records)
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java
index ba2d2ffa5..49f362750 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java
@@ -16,8 +16,11 @@
package org.mybatis.dynamic.sql.insert.render;
import org.mybatis.dynamic.sql.SqlColumn;
+import org.mybatis.dynamic.sql.exception.InvalidSqlException;
import org.mybatis.dynamic.sql.render.RenderingStrategy;
import org.mybatis.dynamic.sql.util.ConstantMapping;
+import org.mybatis.dynamic.sql.util.MappedColumnMapping;
+import org.mybatis.dynamic.sql.util.Messages;
import org.mybatis.dynamic.sql.util.MultiRowInsertMappingVisitor;
import org.mybatis.dynamic.sql.util.NullMapping;
import org.mybatis.dynamic.sql.util.PropertyMapping;
@@ -69,6 +72,22 @@ public FieldAndValueAndParameters visit(RowMapping mapping) {
.build();
}
+ @Override
+ public FieldAndValueAndParameters visit(MappedColumnMapping mapping) {
+ return FieldAndValueAndParameters.withFieldName(mapping.columnName())
+ .withValuePhrase(calculateJdbcPlaceholder(
+ mapping.column(),
+ getMappedPropertyName(mapping.column()))
+ )
+ .build();
+ }
+
+ private String getMappedPropertyName(SqlColumn> column) {
+ return column.javaProperty().orElseThrow(() ->
+ new InvalidSqlException(Messages
+ .getString("ERROR.50", column.name()))); //$NON-NLS-1$
+ }
+
private String calculateJdbcPlaceholder(SqlColumn> column) {
return column.renderingStrategy().orElse(renderingStrategy).getRecordBasedInsertBinding(column, prefix);
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java
index dccf0f14a..a784f6e3b 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java
@@ -18,9 +18,13 @@
import java.util.Optional;
import org.mybatis.dynamic.sql.SqlColumn;
+import org.mybatis.dynamic.sql.exception.InvalidSqlException;
import org.mybatis.dynamic.sql.render.RenderingStrategy;
import org.mybatis.dynamic.sql.util.ConstantMapping;
import org.mybatis.dynamic.sql.util.InsertMappingVisitor;
+import org.mybatis.dynamic.sql.util.MappedColumnMapping;
+import org.mybatis.dynamic.sql.util.MappedColumnWhenPresentMapping;
+import org.mybatis.dynamic.sql.util.Messages;
import org.mybatis.dynamic.sql.util.NullMapping;
import org.mybatis.dynamic.sql.util.PropertyMapping;
import org.mybatis.dynamic.sql.util.PropertyWhenPresentMapping;
@@ -80,6 +84,31 @@ public Optional visit(RowMapping mapping) {
.buildOptional();
}
+ @Override
+ public Optional visit(MappedColumnMapping mapping) {
+ return FieldAndValueAndParameters.withFieldName(mapping.columnName())
+ .withValuePhrase(calculateJdbcPlaceholder(
+ mapping.column(),
+ getMappedPropertyName(mapping.column()))
+ )
+ .buildOptional();
+ }
+
+ @Override
+ public Optional visit(MappedColumnWhenPresentMapping mapping) {
+ if (mapping.shouldRender()) {
+ return visit((MappedColumnMapping) mapping);
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ private String getMappedPropertyName(SqlColumn> column) {
+ return column.javaProperty().orElseThrow(() ->
+ new InvalidSqlException(Messages
+ .getString("ERROR.50", column.name()))); //$NON-NLS-1$
+ }
+
private String calculateJdbcPlaceholder(SqlColumn> column) {
return column.renderingStrategy().orElse(renderingStrategy)
.getRecordBasedInsertBinding(column, "row"); //$NON-NLS-1$
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java
index 19f949f09..34516105b 100644
--- a/src/main/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java
@@ -52,4 +52,8 @@ public interface ColumnMappingVisitor {
R visit(ColumnToColumnMapping mapping);
R visit(RowMapping mapping);
+
+ R visit(MappedColumnMapping mapping);
+
+ R visit(MappedColumnWhenPresentMapping mapping);
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java
index e55e3d100..21303d49b 100644
--- a/src/main/java/org/mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java
@@ -40,4 +40,14 @@ public final R visit(ColumnToColumnMapping columnMapping) {
public final R visit(RowMapping mapping) {
throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_14));
}
+
+ @Override
+ public R visit(MappedColumnMapping mapping) {
+ throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_16));
+ }
+
+ @Override
+ public R visit(MappedColumnWhenPresentMapping mapping) {
+ throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_17));
+ }
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/InternalError.java b/src/main/java/org/mybatis/dynamic/sql/util/InternalError.java
index ed6b0a3cc..e973dad55 100644
--- a/src/main/java/org/mybatis/dynamic/sql/util/InternalError.java
+++ b/src/main/java/org/mybatis/dynamic/sql/util/InternalError.java
@@ -33,7 +33,12 @@ public enum InternalError {
INTERNAL_ERROR_12(12),
INTERNAL_ERROR_13(13),
INTERNAL_ERROR_14(14),
- INTERNAL_ERROR_15(15);
+ INTERNAL_ERROR_15(15),
+ INTERNAL_ERROR_16(16),
+ INTERNAL_ERROR_17(17),
+ INTERNAL_ERROR_18(18),
+ INTERNAL_ERROR_19(19),
+ INTERNAL_ERROR_20(20);
private final int number;
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnMapping.java
new file mode 100644
index 000000000..bef0a57e0
--- /dev/null
+++ b/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnMapping.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2016-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mybatis.dynamic.sql.util;
+
+import org.mybatis.dynamic.sql.SqlColumn;
+
+public class MappedColumnMapping extends AbstractColumnMapping {
+
+ protected MappedColumnMapping(SqlColumn> column) {
+ super(column);
+ }
+
+ @Override
+ public R accept(ColumnMappingVisitor visitor) {
+ return visitor.visit(this);
+ }
+
+ public static MappedColumnMapping of(SqlColumn> column) {
+ return new MappedColumnMapping(column);
+ }
+}
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java
new file mode 100644
index 000000000..2e0729ed0
--- /dev/null
+++ b/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mybatis.dynamic.sql.util;
+
+import org.mybatis.dynamic.sql.SqlColumn;
+
+import java.util.Objects;
+import java.util.function.Supplier;
+
+public class MappedColumnWhenPresentMapping extends MappedColumnMapping {
+ private final Supplier> valueSupplier;
+
+ private MappedColumnWhenPresentMapping(SqlColumn> column, Supplier> valueSupplier) {
+ super(column);
+ this.valueSupplier = Objects.requireNonNull(valueSupplier);
+ }
+
+ public boolean shouldRender() {
+ return valueSupplier.get() != null;
+ }
+
+ @Override
+ public R accept(ColumnMappingVisitor visitor) {
+ return visitor.visit(this);
+ }
+
+ public static MappedColumnWhenPresentMapping of(SqlColumn> column, Supplier> valueSupplier) {
+ return new MappedColumnWhenPresentMapping(column, valueSupplier);
+ }
+}
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java
index 18a75221d..668d064e7 100644
--- a/src/main/java/org/mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java
@@ -20,4 +20,9 @@ public abstract class MultiRowInsertMappingVisitor extends InsertMappingVisit
public final R visit(PropertyWhenPresentMapping mapping) {
throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_12));
}
+
+ @Override
+ public R visit(MappedColumnWhenPresentMapping mapping) {
+ throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_18));
+ }
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java
index 8d06585ab..b6597685c 100644
--- a/src/main/java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java
@@ -30,4 +30,14 @@ public final R visit(PropertyWhenPresentMapping mapping) {
public final R visit(RowMapping mapping) {
throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_15));
}
+
+ @Override
+ public R visit(MappedColumnMapping mapping) {
+ throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_19));
+ }
+
+ @Override
+ public R visit(MappedColumnWhenPresentMapping mapping) {
+ throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_20));
+ }
}
diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties
index 3cf560a78..89ea08e70 100644
--- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties
+++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties
@@ -67,4 +67,5 @@ ERROR.47=A Kotlin case statement must specify a "then" clause for every "when" c
ERROR.48=You cannot call more than one of "forUpdate", "forNoKeyUpdate", "forShare", or "forKeyShare" in a select \
statement
ERROR.49=You cannot call more than one of "skipLocked", or "nowait" in a select statement
+ERROR.50=Mapped column {0} does not have a javaProperty configured
INTERNAL.ERROR=Internal Error {0}
diff --git a/src/test/java/examples/simple/PersonDynamicSqlSupport.java b/src/test/java/examples/simple/PersonDynamicSqlSupport.java
index 215f8a909..ba31eea5d 100644
--- a/src/test/java/examples/simple/PersonDynamicSqlSupport.java
+++ b/src/test/java/examples/simple/PersonDynamicSqlSupport.java
@@ -32,13 +32,21 @@ public final class PersonDynamicSqlSupport {
public static final SqlColumn addressId = person.addressId;
public static final class Person extends SqlTable {
- public final SqlColumn id = column("id", JDBCType.INTEGER);
- public final SqlColumn firstName = column("first_name", JDBCType.VARCHAR);
- public final SqlColumn lastName = column("last_name", JDBCType.VARCHAR, "examples.simple.LastNameTypeHandler");
- public final SqlColumn birthDate = column("birth_date", JDBCType.DATE);
- public final SqlColumn employed = column("employed", JDBCType.VARCHAR, "examples.simple.YesNoTypeHandler");
- public final SqlColumn occupation = column("occupation", JDBCType.VARCHAR);
- public final SqlColumn addressId = column("address_id", JDBCType.INTEGER);
+ public final SqlColumn id = column("id", JDBCType.INTEGER).withJavaProperty("id");
+ public final SqlColumn firstName = column("first_name", JDBCType.VARCHAR)
+ .withJavaProperty("firstName");
+ public final SqlColumn lastName =
+ column("last_name", JDBCType.VARCHAR, "examples.simple.LastNameTypeHandler")
+ .withJavaProperty("lastName");
+ public final SqlColumn birthDate = column("birth_date", JDBCType.DATE)
+ .withJavaProperty("birthDate");
+ public final SqlColumn employed =
+ column("employed", JDBCType.VARCHAR, "examples.simple.YesNoTypeHandler")
+ .withJavaProperty("employed");
+ public final SqlColumn occupation = column("occupation", JDBCType.VARCHAR)
+ .withJavaProperty("occupation");
+ public final SqlColumn addressId = column("address_id", JDBCType.INTEGER)
+ .withJavaProperty("addressId");
public Person() {
super("Person");
diff --git a/src/test/java/examples/simple/PersonMapper.java b/src/test/java/examples/simple/PersonMapper.java
index 819b72c3b..371caaf0b 100644
--- a/src/test/java/examples/simple/PersonMapper.java
+++ b/src/test/java/examples/simple/PersonMapper.java
@@ -106,13 +106,13 @@ default int generalInsert(UnaryOperator completer) {
default int insert(PersonRecord row) {
return MyBatis3Utils.insert(this::insert, row, person, c ->
- c.map(id).toProperty("id")
- .map(firstName).toProperty("firstName")
- .map(lastName).toProperty("lastName")
- .map(birthDate).toProperty("birthDate")
- .map(employed).toProperty("employed")
- .map(occupation).toProperty("occupation")
- .map(addressId).toProperty("addressId")
+ c.withMappedColumn(id)
+ .withMappedColumn(firstName)
+ .withMappedColumn(lastName)
+ .withMappedColumn(birthDate)
+ .withMappedColumn(employed)
+ .withMappedColumn(occupation)
+ .withMappedColumn(addressId)
);
}
@@ -122,25 +122,25 @@ default int insertMultiple(PersonRecord...records) {
default int insertMultiple(Collection records) {
return MyBatis3Utils.insertMultiple(this::insertMultiple, records, person, c ->
- c.map(id).toProperty("id")
- .map(firstName).toProperty("firstName")
- .map(lastName).toProperty("lastName")
- .map(birthDate).toProperty("birthDate")
- .map(employed).toProperty("employed")
- .map(occupation).toProperty("occupation")
- .map(addressId).toProperty("addressId")
+ c.withMappedColumn(id)
+ .withMappedColumn(firstName)
+ .withMappedColumn(lastName)
+ .withMappedColumn(birthDate)
+ .withMappedColumn(employed)
+ .withMappedColumn(occupation)
+ .withMappedColumn(addressId)
);
}
default int insertSelective(PersonRecord row) {
return MyBatis3Utils.insert(this::insert, row, person, c ->
- c.map(id).toPropertyWhenPresent("id", row::id)
- .map(firstName).toPropertyWhenPresent("firstName", row::firstName)
- .map(lastName).toPropertyWhenPresent("lastName", row::lastName)
- .map(birthDate).toPropertyWhenPresent("birthDate", row::birthDate)
- .map(employed).toPropertyWhenPresent("employed", row::employed)
- .map(occupation).toPropertyWhenPresent("occupation", row::occupation)
- .map(addressId).toPropertyWhenPresent("addressId", row::addressId)
+ c.withMappedColumnWhenPresent(id, row::id)
+ .withMappedColumnWhenPresent(firstName, row::firstName)
+ .withMappedColumnWhenPresent(lastName, row::lastName)
+ .withMappedColumnWhenPresent(birthDate, row::birthDate)
+ .withMappedColumnWhenPresent(employed, row::employed)
+ .withMappedColumnWhenPresent(occupation, row::occupation)
+ .withMappedColumnWhenPresent(addressId, row::addressId)
);
}
diff --git a/src/test/java/examples/spring/PersonTemplateTest.java b/src/test/java/examples/spring/PersonTemplateTest.java
index b92c03a50..9e8de9813 100644
--- a/src/test/java/examples/spring/PersonTemplateTest.java
+++ b/src/test/java/examples/spring/PersonTemplateTest.java
@@ -201,9 +201,8 @@ void testFirstNameIn() {
List rows = template.selectList(selectStatement, personRowMapper);
- assertThat(rows).hasSize(2);
-
- assertThat(rows).satisfiesExactly(
+ assertThat(rows).hasSize(2)
+ .satisfiesExactly(
person1 -> assertThat(person1).isNotNull()
.extracting("lastName").isNotNull()
.extracting("name").isEqualTo("Flintstone"),
diff --git a/src/test/java/org/mybatis/dynamic/sql/insert/render/InsertVisitorsTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/render/InsertVisitorsTest.java
new file mode 100644
index 000000000..f44b0930c
--- /dev/null
+++ b/src/test/java/org/mybatis/dynamic/sql/insert/render/InsertVisitorsTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mybatis.dynamic.sql.insert.render;
+
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+import org.junit.jupiter.api.Test;
+import org.mybatis.dynamic.sql.SqlColumn;
+import org.mybatis.dynamic.sql.SqlTable;
+import org.mybatis.dynamic.sql.exception.InvalidSqlException;
+import org.mybatis.dynamic.sql.render.RenderingStrategies;
+import org.mybatis.dynamic.sql.util.MappedColumnMapping;
+import org.mybatis.dynamic.sql.util.Messages;
+
+class InsertVisitorsTest {
+ @Test
+ void testThatMultiRowInsertVisitorErrorsForMappedColumnWhenPropertyIsMissing() {
+ TestTable table = new TestTable();
+ MultiRowValuePhraseVisitor tv = new MultiRowValuePhraseVisitor(RenderingStrategies.MYBATIS3, "prefix");
+ MappedColumnMapping mapping = MappedColumnMapping.of(table.id);
+
+ assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(() -> tv.visit(mapping))
+ .withMessage(Messages.getString("ERROR.50", table.id.name()));
+ }
+
+ @Test
+ void testThatValuePhraseVisitorErrorsForMappedColumnWhenPropertyIsMissing() {
+ TestTable table = new TestTable();
+ ValuePhraseVisitor tv = new ValuePhraseVisitor(RenderingStrategies.MYBATIS3);
+ MappedColumnMapping mapping = MappedColumnMapping.of(table.id);
+
+ assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(() -> tv.visit(mapping))
+ .withMessage(Messages.getString("ERROR.50", table.id.name()));
+ }
+
+ private static class TestTable extends SqlTable {
+ public final SqlColumn id;
+ public final SqlColumn description;
+
+ public TestTable() {
+ super("Test");
+
+ id = column("id");
+ description = column("description");
+ }
+ }
+}
diff --git a/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java b/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java
index 2f17910b2..9369a35ce 100644
--- a/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java
+++ b/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java
@@ -204,6 +204,56 @@ void testThatUpdateVisitorErrorsForRowMapping() {
.withMessage("Internal Error 15");
}
+ @Test
+ void testThatUpdateVisitorErrorsForMappedColumnMapping() {
+ TestTable table = new TestTable();
+ UpdateVisitor tv = new UpdateVisitor();
+ MappedColumnMapping mapping = MappedColumnMapping.of(table.id);
+
+ assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> tv.visit(mapping))
+ .withMessage("Internal Error 19");
+ }
+
+ @Test
+ void testThatUpdateVisitorErrorsForMappedWhenPresentColumnMapping() {
+ TestTable table = new TestTable();
+ UpdateVisitor tv = new UpdateVisitor();
+ MappedColumnWhenPresentMapping mapping = MappedColumnWhenPresentMapping.of(table.id, () -> 1);
+
+ assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> tv.visit(mapping))
+ .withMessage("Internal Error 20");
+ }
+
+ @Test
+ void testThatGeneralInsertVisitorErrorsForMappedColumnMapping() {
+ TestTable table = new TestTable();
+ GeneralInsertVisitor tv = new GeneralInsertVisitor();
+ MappedColumnMapping mapping = MappedColumnMapping.of(table.id);
+
+ assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> tv.visit(mapping))
+ .withMessage("Internal Error 16");
+ }
+
+ @Test
+ void testThatGeneralInsertVisitorErrorsForMappedWhenPresentColumnMapping() {
+ TestTable table = new TestTable();
+ GeneralInsertVisitor tv = new GeneralInsertVisitor();
+ MappedColumnWhenPresentMapping mapping = MappedColumnWhenPresentMapping.of(table.id, () -> 1);
+
+ assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> tv.visit(mapping))
+ .withMessage("Internal Error 17");
+ }
+
+ @Test
+ void testThatMultiRowInsertVisitorErrorsForMappedColumnWhenPresentMapping() {
+ TestTable table = new TestTable();
+ MultiRowInsertVisitor tv = new MultiRowInsertVisitor();
+ MappedColumnWhenPresentMapping mapping = MappedColumnWhenPresentMapping.of(table.id, () -> 1);
+
+ assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> tv.visit(mapping))
+ .withMessage("Internal Error 18");
+ }
+
private static class TestTable extends SqlTable {
public final SqlColumn id;
public final SqlColumn description;
@@ -278,6 +328,16 @@ public String visit(PropertyWhenPresentMapping mapping) {
public String visit(RowMapping mapping) {
return "Row Mapping";
}
+
+ @Override
+ public String visit(MappedColumnMapping mapping) {
+ return "Mapped Column Mapping";
+ }
+
+ @Override
+ public String visit(MappedColumnWhenPresentMapping mapping) {
+ return "Mapped Column When Present Mapping";
+ }
}
private static class UpdateVisitor extends UpdateMappingVisitor {
@@ -349,5 +409,9 @@ public String visit(RowMapping mapping) {
return "Row Mapping";
}
+ @Override
+ public String visit(MappedColumnMapping mapping) {
+ return "Mapped Column Mapping";
+ }
}
}
From 3897fbae98776b337b6bea67592a58bb33c42ae4 Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Fri, 25 Jul 2025 16:58:48 -0400
Subject: [PATCH 05/68] checkstyle
---
.../dynamic/sql/util/MappedColumnWhenPresentMapping.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java
index 2e0729ed0..268cae396 100644
--- a/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java
+++ b/src/main/java/org/mybatis/dynamic/sql/util/MappedColumnWhenPresentMapping.java
@@ -15,11 +15,11 @@
*/
package org.mybatis.dynamic.sql.util;
-import org.mybatis.dynamic.sql.SqlColumn;
-
import java.util.Objects;
import java.util.function.Supplier;
+import org.mybatis.dynamic.sql.SqlColumn;
+
public class MappedColumnWhenPresentMapping extends MappedColumnMapping {
private final Supplier> valueSupplier;
From ac2e6dce4b7c431942902caf6bbd649a84ba22fc Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Fri, 25 Jul 2025 17:21:19 -0400
Subject: [PATCH 06/68] Add Kotlin Support for MappedColumns with inserts
---
.../util/kotlin/KotlinBatchInsertBuilder.kt | 5 ++
.../sql/util/kotlin/KotlinInsertBuilder.kt | 10 ++++
.../kotlin/KotlinMultiRowInsertBuilder.kt | 5 ++
.../kotlin/elements/SqlTableExtensions.kt | 4 +-
.../canonical/PersonDynamicSqlSupport.kt | 16 +++---
.../canonical/PersonMapperExtensions.kt | 56 +++++++++----------
6 files changed, 60 insertions(+), 36 deletions(-)
diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt
index aa2dd3703..fed6bf1d6 100644
--- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt
+++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt
@@ -21,6 +21,7 @@ import org.mybatis.dynamic.sql.insert.BatchInsertDSL
import org.mybatis.dynamic.sql.insert.BatchInsertModel
import org.mybatis.dynamic.sql.util.AbstractColumnMapping
import org.mybatis.dynamic.sql.util.Buildable
+import org.mybatis.dynamic.sql.util.MappedColumnMapping
typealias KotlinBatchInsertCompleter = KotlinBatchInsertBuilder.() -> Unit
@@ -37,6 +38,10 @@ class KotlinBatchInsertBuilder (private val rows: Collection): Build
columnMappings.add(it)
}
+ fun withMappedColumn(column: SqlColumn) {
+ columnMappings.add(MappedColumnMapping.of(column))
+ }
+
override fun build(): BatchInsertModel {
assertNotNull(table, "ERROR.23") //$NON-NLS-1$
return with(BatchInsertDSL.Builder()) {
diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt
index 8b76231f7..6b2784fed 100644
--- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt
+++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt
@@ -21,6 +21,8 @@ import org.mybatis.dynamic.sql.insert.InsertDSL
import org.mybatis.dynamic.sql.insert.InsertModel
import org.mybatis.dynamic.sql.util.AbstractColumnMapping
import org.mybatis.dynamic.sql.util.Buildable
+import org.mybatis.dynamic.sql.util.MappedColumnMapping
+import org.mybatis.dynamic.sql.util.MappedColumnWhenPresentMapping
typealias KotlinInsertCompleter = KotlinInsertBuilder.() -> Unit
@@ -37,6 +39,14 @@ class KotlinInsertBuilder (private val row: T): Buildable withMappedColumn(column: SqlColumn) {
+ columnMappings.add(MappedColumnMapping.of(column))
+ }
+
+ fun withMappedColumnWhenPresent(column: SqlColumn, valueSupplier: () -> Any?) {
+ columnMappings.add(MappedColumnWhenPresentMapping.of(column, valueSupplier))
+ }
+
override fun build(): InsertModel {
assertNotNull(table, "ERROR.25") //$NON-NLS-1$
return with(InsertDSL.Builder()) {
diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt
index b00a62aef..6b3d72d7c 100644
--- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt
+++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt
@@ -21,6 +21,7 @@ import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL
import org.mybatis.dynamic.sql.insert.MultiRowInsertModel
import org.mybatis.dynamic.sql.util.AbstractColumnMapping
import org.mybatis.dynamic.sql.util.Buildable
+import org.mybatis.dynamic.sql.util.MappedColumnMapping
typealias KotlinMultiRowInsertCompleter = KotlinMultiRowInsertBuilder.() -> Unit
@@ -37,6 +38,10 @@ class KotlinMultiRowInsertBuilder (private val rows: Collection): Bu
columnMappings.add(it)
}
+ fun withMappedColumn(column: SqlColumn) {
+ columnMappings.add(MappedColumnMapping.of(column))
+ }
+
override fun build(): MultiRowInsertModel {
assertNotNull(table, "ERROR.26") //$NON-NLS-1$
return with(MultiRowInsertDSL.Builder()) {
diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt
index bbd79dcd7..24962ef01 100644
--- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt
+++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt
@@ -34,7 +34,8 @@ fun SqlTable.column(
typeHandler: String? = null,
renderingStrategy: RenderingStrategy? = null,
parameterTypeConverter: ((T?) -> Any?) = { it },
- javaType: KClass? = null
+ javaType: KClass? = null,
+ javaProperty: String? = null,
): SqlColumn = SqlColumn.Builder().run {
withTable(this@column)
withName(name)
@@ -43,5 +44,6 @@ fun SqlTable.column(
withRenderingStrategy(renderingStrategy)
withParameterTypeConverter(parameterTypeConverter)
withJavaType(javaType?.java)
+ withJavaProperty(javaProperty)
build()
}
diff --git a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt
index 94e60161d..dbfbbecba 100644
--- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt
+++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt
@@ -31,20 +31,22 @@ object PersonDynamicSqlSupport {
val addressId = person.addressId
class Person : SqlTable("Person") {
- val id = column(name = "id", jdbcType = JDBCType.INTEGER)
- val firstName = column(name = "first_name", jdbcType = JDBCType.VARCHAR)
+ val id = column(name = "id", jdbcType = JDBCType.INTEGER, javaProperty = "id")
+ val firstName = column(name = "first_name", jdbcType = JDBCType.VARCHAR, javaProperty = "firstName")
val lastName = column(
name = "last_name",
jdbcType = JDBCType.VARCHAR,
- typeHandler = "examples.kotlin.mybatis3.canonical.LastNameTypeHandler"
+ typeHandler = "examples.kotlin.mybatis3.canonical.LastNameTypeHandler",
+ javaProperty = "lastName"
)
- val birthDate = column(name = "birth_date", jdbcType = JDBCType.DATE)
+ val birthDate = column(name = "birth_date", jdbcType = JDBCType.DATE, javaProperty = "birthDate")
val employed = column(
name = "employed",
JDBCType.VARCHAR,
- typeHandler = "examples.kotlin.mybatis3.canonical.YesNoTypeHandler"
+ typeHandler = "examples.kotlin.mybatis3.canonical.YesNoTypeHandler",
+ javaProperty = "employed"
)
- val occupation = column(name = "occupation", jdbcType = JDBCType.VARCHAR)
- val addressId = column(name = "address_id", jdbcType = JDBCType.INTEGER)
+ val occupation = column(name = "occupation", jdbcType = JDBCType.VARCHAR, javaProperty = "occupation")
+ val addressId = column(name = "address_id", jdbcType = JDBCType.INTEGER, javaProperty = "addressId")
}
}
diff --git a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt
index 237b5ebd7..184805bae 100644
--- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt
+++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt
@@ -65,13 +65,13 @@ fun PersonMapper.deleteByPrimaryKey(id_: Int) =
fun PersonMapper.insert(record: PersonRecord) =
insert(this::insert, record, person) {
- map(id) toProperty "id"
- map(firstName) toProperty "firstName"
- map(lastName) toProperty "lastName"
- map(birthDate) toProperty "birthDate"
- map(employed) toProperty "employed"
- map(occupation) toProperty "occupation"
- map(addressId) toProperty "addressId"
+ withMappedColumn(id)
+ withMappedColumn(firstName)
+ withMappedColumn(lastName)
+ withMappedColumn(birthDate)
+ withMappedColumn(employed)
+ withMappedColumn(occupation)
+ withMappedColumn(addressId)
}
fun PersonMapper.generalInsert(completer: GeneralInsertCompleter) =
@@ -85,13 +85,13 @@ fun PersonMapper.insertBatch(vararg records: PersonRecord): List =
fun PersonMapper.insertBatch(records: Collection): List =
insertBatch(this::insert, records, person) {
- map(id) toProperty "id"
- map(firstName) toProperty "firstName"
- map(lastName) toProperty "lastName"
- map(birthDate) toProperty "birthDate"
- map(employed) toProperty "employed"
- map(occupation) toProperty "occupation"
- map(addressId) toProperty "addressId"
+ withMappedColumn(id)
+ withMappedColumn(firstName)
+ withMappedColumn(lastName)
+ withMappedColumn(birthDate)
+ withMappedColumn(employed)
+ withMappedColumn(occupation)
+ withMappedColumn(addressId)
}
fun PersonMapper.insertMultiple(vararg records: PersonRecord) =
@@ -99,24 +99,24 @@ fun PersonMapper.insertMultiple(vararg records: PersonRecord) =
fun PersonMapper.insertMultiple(records: Collection) =
insertMultiple(this::insertMultiple, records, person) {
- map(id) toProperty "id"
- map(firstName) toProperty "firstName"
- map(lastName) toProperty "lastName"
- map(birthDate) toProperty "birthDate"
- map(employed) toProperty "employed"
- map(occupation) toProperty "occupation"
- map(addressId) toProperty "addressId"
+ withMappedColumn(id)
+ withMappedColumn(firstName)
+ withMappedColumn(lastName)
+ withMappedColumn(birthDate)
+ withMappedColumn(employed)
+ withMappedColumn(occupation)
+ withMappedColumn(addressId)
}
fun PersonMapper.insertSelective(record: PersonRecord) =
insert(this::insert, record, person) {
- map(id).toPropertyWhenPresent("id", record::id)
- map(firstName).toPropertyWhenPresent("firstName", record::firstName)
- map(lastName).toPropertyWhenPresent("lastName", record::lastName)
- map(birthDate).toPropertyWhenPresent("birthDate", record::birthDate)
- map(employed).toPropertyWhenPresent("employed", record::employed)
- map(occupation).toPropertyWhenPresent("occupation", record::occupation)
- map(addressId).toPropertyWhenPresent("addressId", record::addressId)
+ withMappedColumnWhenPresent(id, record::id)
+ withMappedColumnWhenPresent(firstName, record::firstName)
+ withMappedColumnWhenPresent(lastName, record::lastName)
+ withMappedColumnWhenPresent(birthDate, record::birthDate)
+ withMappedColumnWhenPresent(employed, record::employed)
+ withMappedColumnWhenPresent(occupation, record::occupation)
+ withMappedColumnWhenPresent(addressId, record::addressId)
}
private val columnList = listOf(id `as` "A_ID", firstName, lastName, birthDate, employed, occupation, addressId)
From 0b8c93e924cdfe50f01eaf421f6e8f3645a73a28 Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Mon, 28 Jul 2025 09:50:49 -0400
Subject: [PATCH 07/68] Add MappedColumn support for batch inserts in Java
---
.../org/mybatis/dynamic/sql/insert/BatchInsertDSL.java | 6 ++++++
.../always/spring/GeneratedAlwaysDynamicSqlSupport.java | 8 ++++----
.../java/examples/generated/always/spring/SpringTest.java | 6 +++---
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java
index 71bc350d6..c2938e9c1 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java
@@ -27,6 +27,7 @@
import org.mybatis.dynamic.sql.util.AbstractColumnMapping;
import org.mybatis.dynamic.sql.util.Buildable;
import org.mybatis.dynamic.sql.util.ConstantMapping;
+import org.mybatis.dynamic.sql.util.MappedColumnMapping;
import org.mybatis.dynamic.sql.util.NullMapping;
import org.mybatis.dynamic.sql.util.PropertyMapping;
import org.mybatis.dynamic.sql.util.RowMapping;
@@ -48,6 +49,11 @@ public ColumnMappingFinisher map(SqlColumn column) {
return new ColumnMappingFinisher<>(column);
}
+ public BatchInsertDSL withMappedColumn(SqlColumn column) {
+ columnMappings.add(MappedColumnMapping.of(column));
+ return this;
+ }
+
@Override
public BatchInsertModel build() {
return BatchInsertModel.withRecords(records)
diff --git a/src/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java b/src/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java
index 9a96f8bc2..cc0af0058 100644
--- a/src/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java
+++ b/src/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java
@@ -26,10 +26,10 @@ public final class GeneratedAlwaysDynamicSqlSupport {
public static final SqlColumn fullName = generatedAlways.fullName;
public static final class GeneratedAlways extends SqlTable {
- public final SqlColumn id = column("id");
- public final SqlColumn firstName = column("first_name");
- public final SqlColumn lastName = column("last_name");
- public final SqlColumn fullName = column("full_name");
+ public final SqlColumn id = column("id").withJavaProperty("id");
+ public final SqlColumn firstName = column("first_name").withJavaProperty("firstName");
+ public final SqlColumn lastName = column("last_name").withJavaProperty("lastName");
+ public final SqlColumn fullName = column("full_name").withJavaProperty("fullName");
public GeneratedAlways() {
super("GeneratedAlways");
diff --git a/src/test/java/examples/generated/always/spring/SpringTest.java b/src/test/java/examples/generated/always/spring/SpringTest.java
index 59a241368..5fd9b59d1 100644
--- a/src/test/java/examples/generated/always/spring/SpringTest.java
+++ b/src/test/java/examples/generated/always/spring/SpringTest.java
@@ -241,9 +241,9 @@ void testInsertBatch() {
BatchInsert batchInsert = insertBatch(records)
.into(generatedAlways)
- .map(id).toProperty("id")
- .map(firstName).toProperty("firstName")
- .map(lastName).toProperty("lastName")
+ .withMappedColumn(id)
+ .withMappedColumn(firstName)
+ .withMappedColumn(lastName)
.build()
.render(RenderingStrategies.SPRING_NAMED_PARAMETER);
From bc175524be9c2175c826cdde71e65b33617fdbb6 Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Tue, 29 Jul 2025 14:48:38 -0400
Subject: [PATCH 08/68] Documentation
---
CHANGELOG.md | 2 +
src/site/markdown/docs/insert.md | 60 +++++++++++++++++++
.../examples/simple/PersonMapperTest.java | 22 +++++++
3 files changed, 84 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c65f2c09c..9375a78e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -107,6 +107,8 @@ Runtime behavior changes:
are not supported by the library out of the box. The statement renderers now call methods `renderCondition` and
`renderLeftColumn` that you can override to implement any rendering you need. In addition, we've made `filter` and
`map` support optional if you implement custom conditions
+- Added support for configuring a Java property name to be associated with an `SqlColumn`. This property name can be
+ used with the record based insert methods to reduce the boilerplate code for mapping columns to Java properties.
## Release 1.5.2 - June 3, 2024
diff --git a/src/site/markdown/docs/insert.md b/src/site/markdown/docs/insert.md
index b7fe11a70..6ac2e0302 100644
--- a/src/site/markdown/docs/insert.md
+++ b/src/site/markdown/docs/insert.md
@@ -44,6 +44,66 @@ Notice the `map` method. It is used to map a database column to an attribute of
5. `map(column).toPropertyWhenPresent(property, Supplier> valueSupplier)` will insert a value from the record into a column if the value is non-null. The value of the property will be bound to the SQL statement as a prepared statement parameter. This is used to generate a "selective" insert as defined in MyBatis Generator.
6. `map(column).toRow()` will insert the record itself into a column. This is appropriate when the "record" is a simple class like Integer or String.
+### Mapped Columns
+Starting in version 2.0.0 there are two new methods:
+
+1. `withMappedColumn(SqlColumn)` that will map a database column to a Java property based on a property name that can
+ be configured in an `SQLColumn`.
+2. `withMappedColumnWhenPresent(SqlColumn, Supplier)` that will map a database column to a Java property based on a
+ property name that can be configured in an `SQLColumn`. The insert statement will only contain the mapped column when
+ the Supplier returns a non-null value (this method is for single record inserts only).
+
+This will allow you to configure mappings in a single place (the `SqlColumn`) and reuse them in multiple insert
+statements. For example:
+
+```java
+public final class PersonDynamicSqlSupport {
+ public static final Person person = new Person();
+ public static final SqlColumn id = person.id;
+ public static final SqlColumn firstName = person.firstName;
+ public static final SqlColumn lastName = person.lastName;
+
+ public static final class Person extends SqlTable {
+ public final SqlColumn id = column("id", JDBCType.INTEGER).withJavaProperty("id");
+ public final SqlColumn firstName = column("first_name", JDBCType.VARCHAR)
+ .withJavaProperty("firstName");
+ public final SqlColumn lastName =
+ column("last_name", JDBCType.VARCHAR).withJavaProperty("lastName");
+
+ public Person() {
+ super("Person");
+ }
+ }
+}
+```
+
+In this support class, each `SqlColumn` has a configured Java property. This property can be accessed in record based
+inserts in the following way:
+
+```java
+ @Test
+ void testRawInsert() {
+ try (SqlSession session = sqlSessionFactory.openSession()) {
+ PersonMapper mapper = session.getMapper(PersonMapper.class);
+ PersonRecord row = new PersonRecord(100, "Joe", "Jones");
+
+ InsertStatementProvider insertStatement = insert(row).into(person)
+ .withMappedColumn(id)
+ .withMappedColumn(firstName)
+ .withMappedColumn(lastName)
+ .build().render(RenderingStrategies.MYBATIS3);
+
+ int rows = mapper.insert(insertStatement);
+ assertThat(rows).isEqualTo(1);
+ }
+ }
+```
+
+In this test, the mapping between a column and the property of a record is calculated by reading the configured Java
+property for each column.
+
+These new methods are available for the record based insert statements (`insert`, `insertMultiple`, `insertBatch`).
+
### Annotated Mapper for Single Row Insert Statements
The InsertStatementProvider object can be used as a parameter to a MyBatis mapper method directly. If you
are using an annotated mapper, the insert method should look like this (with @Options added for generated values if necessary):
diff --git a/src/test/java/examples/simple/PersonMapperTest.java b/src/test/java/examples/simple/PersonMapperTest.java
index b02d52c4c..ca1e90792 100644
--- a/src/test/java/examples/simple/PersonMapperTest.java
+++ b/src/test/java/examples/simple/PersonMapperTest.java
@@ -53,6 +53,7 @@
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
import org.mybatis.dynamic.sql.exception.NonRenderingWhereClauseException;
import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider;
+import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.CountDSLCompleter;
import org.mybatis.dynamic.sql.select.SelectDSLCompleter;
@@ -338,6 +339,27 @@ void testInsert() {
}
}
+ @Test
+ void testRawInsert() {
+ try (SqlSession session = sqlSessionFactory.openSession()) {
+ PersonMapper mapper = session.getMapper(PersonMapper.class);
+ PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1);
+
+ InsertStatementProvider insertStatement = insert(row).into(person)
+ .withMappedColumn(id)
+ .withMappedColumn(firstName)
+ .withMappedColumn(lastName)
+ .withMappedColumn(birthDate)
+ .withMappedColumn(employed)
+ .withMappedColumn(occupation)
+ .withMappedColumn(addressId)
+ .build().render(RenderingStrategies.MYBATIS3);
+
+ int rows = mapper.insert(insertStatement);
+ assertThat(rows).isEqualTo(1);
+ }
+ }
+
@Test
void testGeneralInsert() {
try (SqlSession session = sqlSessionFactory.openSession()) {
From 32bba95a4bbc6d835a2b3cd94dde17c0bfbb0812 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 30 Jul 2025 17:46:49 +0000
Subject: [PATCH 09/68] Update dependency com.mysql:mysql-connector-j to v9.4.0
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 7c2cdb32c..e050c200a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -214,7 +214,7 @@
com.mysql
mysql-connector-j
- 9.3.0
+ 9.4.0
test
From a0470e2e7a7263a40950dd74c4bb021b92d00718 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 7 Aug 2025 16:34:48 +0000
Subject: [PATCH 10/68] Update dependency org.assertj:assertj-core to v3.27.4
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index e050c200a..1da18a04e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,7 +136,7 @@
org.assertj
assertj-core
- 3.27.3
+ 3.27.4
test
From 2e38280474d4b8e2a1d9e64998a654c0c75fe1b4 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 8 Aug 2025 20:34:00 +0000
Subject: [PATCH 11/68] Update dependency org.mariadb.jdbc:mariadb-java-client
to v3.5.5
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 1da18a04e..002cfc078 100644
--- a/pom.xml
+++ b/pom.xml
@@ -202,7 +202,7 @@
org.mariadb.jdbc
mariadb-java-client
- 3.5.4
+ 3.5.5
test
From 626112b7bcea0d738f5a2c5198f2e2bc98109393 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 11 Aug 2025 14:03:39 +0000
Subject: [PATCH 12/68] Update actions/checkout action to v5
---
.github/workflows/ci.yaml | 2 +-
.github/workflows/codeql.yml | 2 +-
.github/workflows/coveralls.yaml | 2 +-
.github/workflows/site.yaml | 2 +-
.github/workflows/sonar.yaml | 2 +-
.github/workflows/sonatype.yaml | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 66bba3618..9e7986a3f 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -18,7 +18,7 @@ jobs:
name: Test JDK ${{ matrix.java }}, ${{ matrix.os }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up JDK ${{ matrix.java }} ${{ matrix.distribution }}
uses: actions/setup-java@v4
with:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 8e5c9c4b6..3073c7b96 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -25,7 +25,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v4
diff --git a/.github/workflows/coveralls.yaml b/.github/workflows/coveralls.yaml
index b4aaaa991..746fd407a 100644
--- a/.github/workflows/coveralls.yaml
+++ b/.github/workflows/coveralls.yaml
@@ -9,7 +9,7 @@ jobs:
if: github.repository_owner == 'mybatis'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v4
with:
diff --git a/.github/workflows/site.yaml b/.github/workflows/site.yaml
index de1babe41..6a6d29d76 100644
--- a/.github/workflows/site.yaml
+++ b/.github/workflows/site.yaml
@@ -13,7 +13,7 @@ jobs:
if: github.repository_owner == 'mybatis' && ! contains(toJSON(github.event.head_commit.message), '[maven-release-plugin]')
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v4
with:
diff --git a/.github/workflows/sonar.yaml b/.github/workflows/sonar.yaml
index 33c70609c..cd1de642c 100644
--- a/.github/workflows/sonar.yaml
+++ b/.github/workflows/sonar.yaml
@@ -12,7 +12,7 @@ jobs:
if: github.repository_owner == 'mybatis'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
diff --git a/.github/workflows/sonatype.yaml b/.github/workflows/sonatype.yaml
index c922f382c..59100a36f 100644
--- a/.github/workflows/sonatype.yaml
+++ b/.github/workflows/sonatype.yaml
@@ -12,7 +12,7 @@ jobs:
if: github.repository_owner == 'mybatis' && ! contains(toJSON(github.event.head_commit.message), '[maven-release-plugin]')
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v4
with:
From 997a11b1c93ab69ff894cd749600e0ed1ba96256 Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Mon, 11 Aug 2025 11:08:57 -0400
Subject: [PATCH 13/68] Remove copy/paste code
---
.../sql/insert/render/InsertRenderingUtilities.java | 9 +++++++++
.../sql/insert/render/MultiRowValuePhraseVisitor.java | 10 +---------
.../dynamic/sql/insert/render/ValuePhraseVisitor.java | 10 +---------
3 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java
index de529a2b4..a65b56b85 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java
@@ -17,7 +17,10 @@
import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore;
+import org.mybatis.dynamic.sql.SqlColumn;
import org.mybatis.dynamic.sql.SqlTable;
+import org.mybatis.dynamic.sql.exception.InvalidSqlException;
+import org.mybatis.dynamic.sql.util.Messages;
public class InsertRenderingUtilities {
private InsertRenderingUtilities() {}
@@ -33,4 +36,10 @@ public static String calculateInsertStatement(SqlTable table, FieldAndValueColle
public static String calculateInsertStatementStart(SqlTable table) {
return "insert into " + table.tableName(); //$NON-NLS-1$
}
+
+ public static String getMappedPropertyName(SqlColumn> column) {
+ return column.javaProperty().orElseThrow(() ->
+ new InvalidSqlException(Messages
+ .getString("ERROR.50", column.name()))); //$NON-NLS-1$
+ }
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java
index 49f362750..216fdfcbf 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java
@@ -16,11 +16,9 @@
package org.mybatis.dynamic.sql.insert.render;
import org.mybatis.dynamic.sql.SqlColumn;
-import org.mybatis.dynamic.sql.exception.InvalidSqlException;
import org.mybatis.dynamic.sql.render.RenderingStrategy;
import org.mybatis.dynamic.sql.util.ConstantMapping;
import org.mybatis.dynamic.sql.util.MappedColumnMapping;
-import org.mybatis.dynamic.sql.util.Messages;
import org.mybatis.dynamic.sql.util.MultiRowInsertMappingVisitor;
import org.mybatis.dynamic.sql.util.NullMapping;
import org.mybatis.dynamic.sql.util.PropertyMapping;
@@ -77,17 +75,11 @@ public FieldAndValueAndParameters visit(MappedColumnMapping mapping) {
return FieldAndValueAndParameters.withFieldName(mapping.columnName())
.withValuePhrase(calculateJdbcPlaceholder(
mapping.column(),
- getMappedPropertyName(mapping.column()))
+ InsertRenderingUtilities.getMappedPropertyName(mapping.column()))
)
.build();
}
- private String getMappedPropertyName(SqlColumn> column) {
- return column.javaProperty().orElseThrow(() ->
- new InvalidSqlException(Messages
- .getString("ERROR.50", column.name()))); //$NON-NLS-1$
- }
-
private String calculateJdbcPlaceholder(SqlColumn> column) {
return column.renderingStrategy().orElse(renderingStrategy).getRecordBasedInsertBinding(column, prefix);
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java
index a784f6e3b..d628c77ef 100644
--- a/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java
+++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java
@@ -18,13 +18,11 @@
import java.util.Optional;
import org.mybatis.dynamic.sql.SqlColumn;
-import org.mybatis.dynamic.sql.exception.InvalidSqlException;
import org.mybatis.dynamic.sql.render.RenderingStrategy;
import org.mybatis.dynamic.sql.util.ConstantMapping;
import org.mybatis.dynamic.sql.util.InsertMappingVisitor;
import org.mybatis.dynamic.sql.util.MappedColumnMapping;
import org.mybatis.dynamic.sql.util.MappedColumnWhenPresentMapping;
-import org.mybatis.dynamic.sql.util.Messages;
import org.mybatis.dynamic.sql.util.NullMapping;
import org.mybatis.dynamic.sql.util.PropertyMapping;
import org.mybatis.dynamic.sql.util.PropertyWhenPresentMapping;
@@ -89,7 +87,7 @@ public Optional visit(MappedColumnMapping mapping) {
return FieldAndValueAndParameters.withFieldName(mapping.columnName())
.withValuePhrase(calculateJdbcPlaceholder(
mapping.column(),
- getMappedPropertyName(mapping.column()))
+ InsertRenderingUtilities.getMappedPropertyName(mapping.column()))
)
.buildOptional();
}
@@ -103,12 +101,6 @@ public Optional visit(MappedColumnWhenPresentMapping
}
}
- private String getMappedPropertyName(SqlColumn> column) {
- return column.javaProperty().orElseThrow(() ->
- new InvalidSqlException(Messages
- .getString("ERROR.50", column.name()))); //$NON-NLS-1$
- }
-
private String calculateJdbcPlaceholder(SqlColumn> column) {
return column.renderingStrategy().orElse(renderingStrategy)
.getRecordBasedInsertBinding(column, "row"); //$NON-NLS-1$
From 52d98e45ec9129011aa76c7069f00bb332ba46ce Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 14 Aug 2025 11:57:15 +0000
Subject: [PATCH 14/68] Update dependency org.springframework:spring-jdbc to
v6.2.10
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 002cfc078..fb25fa99b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,7 +103,7 @@
org.springframework
spring-jdbc
- 6.2.9
+ 6.2.10
provided
true
From 39929c085d3a1a153fa47fa4e4932fb46eff9ffb Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 21 Aug 2025 05:46:56 +0000
Subject: [PATCH 15/68] Update actions/setup-java action to v5
---
.github/workflows/ci.yaml | 2 +-
.github/workflows/codeql.yml | 2 +-
.github/workflows/coveralls.yaml | 2 +-
.github/workflows/site.yaml | 2 +-
.github/workflows/sonar.yaml | 2 +-
.github/workflows/sonatype.yaml | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 9e7986a3f..0261021ce 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@v5
- name: Set up JDK ${{ matrix.java }} ${{ matrix.distribution }}
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
java-version: ${{ matrix.java }}
distribution: ${{ matrix.distribution }}
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 3073c7b96..1bf6638ba 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -28,7 +28,7 @@ jobs:
uses: actions/checkout@v5
- name: Setup Java
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
cache: maven
distribution: 'temurin'
diff --git a/.github/workflows/coveralls.yaml b/.github/workflows/coveralls.yaml
index 746fd407a..09ab9b4a7 100644
--- a/.github/workflows/coveralls.yaml
+++ b/.github/workflows/coveralls.yaml
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@v5
- name: Set up JDK
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
cache: maven
distribution: temurin
diff --git a/.github/workflows/site.yaml b/.github/workflows/site.yaml
index 6a6d29d76..17572ee8e 100644
--- a/.github/workflows/site.yaml
+++ b/.github/workflows/site.yaml
@@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v5
- name: Set up JDK
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
cache: maven
distribution: temurin
diff --git a/.github/workflows/sonar.yaml b/.github/workflows/sonar.yaml
index cd1de642c..a43dd7198 100644
--- a/.github/workflows/sonar.yaml
+++ b/.github/workflows/sonar.yaml
@@ -17,7 +17,7 @@ jobs:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
- name: Set up JDK
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
cache: maven
distribution: temurin
diff --git a/.github/workflows/sonatype.yaml b/.github/workflows/sonatype.yaml
index 59100a36f..9f47d2039 100644
--- a/.github/workflows/sonatype.yaml
+++ b/.github/workflows/sonatype.yaml
@@ -14,7 +14,7 @@ jobs:
steps:
- uses: actions/checkout@v5
- name: Set up JDK
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
cache: maven
distribution: temurin
From 89b301852506bb272f8931d22569742b8f59fd9b Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 11 Sep 2025 10:46:51 +0000
Subject: [PATCH 16/68] Update dependency org.springframework:spring-jdbc to
v6.2.11
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index fb25fa99b..35fdaae2f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,7 +103,7 @@
org.springframework
spring-jdbc
- 6.2.10
+ 6.2.11
provided
true
From d38e5d85a6b2141e6290a182966a008a271c9617 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 12 Sep 2025 16:12:03 +0000
Subject: [PATCH 17/68] Update dependency org.mariadb.jdbc:mariadb-java-client
to v3.5.6
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 35fdaae2f..eaf09ff7c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -202,7 +202,7 @@
org.mariadb.jdbc
mariadb-java-client
- 3.5.5
+ 3.5.6
test
From c2f6a262c75e75acea6b5f14f8d4793e1d562c49 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 17 Sep 2025 20:44:34 +0000
Subject: [PATCH 18/68] Update spring batch to v5.2.3
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index eaf09ff7c..276e6d7a3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,7 +61,7 @@
17
17
5.13.4
- 5.2.2
+ 5.2.3
checkstyle-override.xml
From 72776b1bd6b5229f2e731940b55a97d5f09734c5 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 19 Sep 2025 01:14:38 +0000
Subject: [PATCH 19/68] Update dependency org.assertj:assertj-core to v3.27.5
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index eaf09ff7c..7ebf954f1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,7 +136,7 @@
org.assertj
assertj-core
- 3.27.4
+ 3.27.5
test
From 98537da63418b4610e4b2fd381107d2397f1e3d6 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 19 Sep 2025 01:14:41 +0000
Subject: [PATCH 20/68] Update dependency org.postgresql:postgresql to v42.7.8
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index eaf09ff7c..ae782dd02 100644
--- a/pom.xml
+++ b/pom.xml
@@ -190,7 +190,7 @@
org.postgresql
postgresql
- 42.7.7
+ 42.7.8
test
From e3cd5cd83d9b7b7e57d9b6a7ef4376022620f920 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 22 Sep 2025 18:58:14 +0000
Subject: [PATCH 21/68] Update dependency org.assertj:assertj-core to v3.27.6
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index fdb2a456a..5e5127f20 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,7 +136,7 @@
org.assertj
assertj-core
- 3.27.5
+ 3.27.6
test
From 1842d42bc6122f8a08c1544e7f5499849dfad204 Mon Sep 17 00:00:00 2001
From: bee0511
Date: Mon, 29 Sep 2025 16:32:17 -0500
Subject: [PATCH 22/68] fix flaky test in
DeprecatedJoinMapperTest#testFullJoinWithoutAliases
---
.../kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt
index d712c46c6..afaa874b3 100644
--- a/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt
+++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt
@@ -276,17 +276,17 @@ class DeprecatedJoinMapperTest {
assertThat(rows).hasSize(6)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[3]).containsExactly(
+ assertThat(rows[3]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[5]).containsExactly(
+ assertThat(rows[5]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
From b5e30472147db6fea01e02c08fcac58faf13f5d3 Mon Sep 17 00:00:00 2001
From: bee0511
Date: Tue, 30 Sep 2025 00:32:32 -0500
Subject: [PATCH 23/68] fix other flaky tests within DeprecatedJoinMapperTest
---
.../joins/DeprecatedJoinMapperTest.kt | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt
index afaa874b3..4586f72d3 100644
--- a/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt
+++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt
@@ -324,12 +324,12 @@ class DeprecatedJoinMapperTest {
assertThat(rows).hasSize(5)
- assertThat(rows[2]).containsExactly(
+ assertThat(rows[2]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -375,12 +375,12 @@ class DeprecatedJoinMapperTest {
assertThat(rows).hasSize(5)
- assertThat(rows[2]).containsExactly(
+ assertThat(rows[2]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -418,12 +418,12 @@ class DeprecatedJoinMapperTest {
assertThat(rows).hasSize(5)
- assertThat(rows[2]).containsExactly(
+ assertThat(rows[2]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -461,12 +461,12 @@ class DeprecatedJoinMapperTest {
assertThat(rows).hasSize(5)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -512,12 +512,12 @@ class DeprecatedJoinMapperTest {
assertThat(rows).hasSize(5)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -555,12 +555,12 @@ class DeprecatedJoinMapperTest {
assertThat(rows).hasSize(5)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
From 91f0a22d53d5206a7bea077019706ee3db7177a9 Mon Sep 17 00:00:00 2001
From: bee0511
Date: Tue, 30 Sep 2025 00:43:51 -0500
Subject: [PATCH 24/68] fix flaky tests in JoinMapperNewSyntaxTest
---
.../mybatis3/joins/JoinMapperNewSyntaxTest.kt | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt
index 3274d0595..50f813d86 100644
--- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt
+++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt
@@ -407,17 +407,17 @@ class JoinMapperNewSyntaxTest {
assertThat(rows).hasSize(6)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[3]).containsExactly(
+ assertThat(rows[3]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[5]).containsExactly(
+ assertThat(rows[5]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -455,12 +455,12 @@ class JoinMapperNewSyntaxTest {
assertThat(rows).hasSize(5)
- assertThat(rows[2]).containsExactly(
+ assertThat(rows[2]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -504,12 +504,12 @@ class JoinMapperNewSyntaxTest {
assertThat(rows).hasSize(5)
- assertThat(rows[2]).containsExactly(
+ assertThat(rows[2]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -547,12 +547,12 @@ class JoinMapperNewSyntaxTest {
assertThat(rows).hasSize(5)
- assertThat(rows[2]).containsExactly(
+ assertThat(rows[2]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 6)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -590,12 +590,12 @@ class JoinMapperNewSyntaxTest {
assertThat(rows).hasSize(5)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -639,12 +639,12 @@ class JoinMapperNewSyntaxTest {
assertThat(rows).hasSize(5)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -682,12 +682,12 @@ class JoinMapperNewSyntaxTest {
assertThat(rows).hasSize(5)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("DESCRIPTION", "Catcher Glove"),
entry("ITEM_ID", 55)
)
- assertThat(rows[4]).containsExactly(
+ assertThat(rows[4]).containsOnly(
entry("ORDER_ID", 2),
entry("QUANTITY", 1),
entry("DESCRIPTION", "Outfield Glove"),
@@ -720,7 +720,7 @@ class JoinMapperNewSyntaxTest {
val rows = mapper.selectManyMappedRows(selectStatement)
assertThat(rows).hasSize(1)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("USER_ID", 2),
entry("USER_NAME", "Barney"),
)
@@ -752,7 +752,7 @@ class JoinMapperNewSyntaxTest {
val rows = mapper.selectManyMappedRows(selectStatement)
assertThat(rows).hasSize(1)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("USER_ID", 2),
entry("USER_NAME", "Barney"),
)
@@ -783,7 +783,7 @@ class JoinMapperNewSyntaxTest {
val rows = mapper.selectManyMappedRows(selectStatement)
assertThat(rows).hasSize(1)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("USER_ID", 2),
entry("USER_NAME", "Barney"),
)
@@ -814,7 +814,7 @@ class JoinMapperNewSyntaxTest {
val rows = mapper.selectManyMappedRows(selectStatement)
assertThat(rows).hasSize(1)
- assertThat(rows[0]).containsExactly(
+ assertThat(rows[0]).containsOnly(
entry("USER_ID", 2),
entry("USER_NAME", "Barney"),
)
From 834275420a3cdfde7c82a584b2a7cb1f68750d6d Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 30 Sep 2025 09:55:48 +0000
Subject: [PATCH 25/68] Update junit-framework monorepo to v6
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 5e5127f20..b0a8bb868 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,7 +60,7 @@
17
17
17
- 5.13.4
+ 6.0.0
5.2.3
checkstyle-override.xml
From 22acd90baece24e7a0a7d5b0e10b437b012bf6c2 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 30 Sep 2025 17:09:16 +0000
Subject: [PATCH 26/68] Update dependency ch.qos.logback:logback-classic to
v1.5.19
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 5e5127f20..87c608a43 100644
--- a/pom.xml
+++ b/pom.xml
@@ -172,7 +172,7 @@
ch.qos.logback
logback-classic
- 1.5.18
+ 1.5.19
test
From 970a851f590fc301340aa8686b1457ec85942bb0 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sun, 5 Oct 2025 00:25:35 +0000
Subject: [PATCH 27/68] Update dependency org.mybatis:mybatis-parent to v51
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 6d1d0fb6a..c3b07343c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
org.mybatis
mybatis-parent
- 50
+ 51
org.mybatis.dynamic-sql
From 4e09d6ff64388ea7425aa7fe39c8777c2b0755b6 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 7 Oct 2025 15:59:50 +0000
Subject: [PATCH 28/68] Update github/codeql-action action to v4
---
.github/workflows/codeql.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 1bf6638ba..1d481b2df 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -35,15 +35,15 @@ jobs:
java-version: 21
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
- uses: github/codeql-action/autobuild@v3
+ uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"
From 02fce4bf03a845ee6ac86fed177990fe347c9b41 Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Tue, 7 Oct 2025 13:59:22 -0400
Subject: [PATCH 29/68] Fix a few more potentially flakey tests
---
src/test/java/examples/simple/PersonMapperTest.java | 2 +-
.../examples/type_conversion/TypeConversionTest.java | 2 +-
.../dynamic/sql/util/FragmentCollectorTest.java | 2 +-
.../where/render/OptionalCriterionRenderTest.java | 12 ++++++------
.../kotlin/spring/canonical/KotlinElementsTest.kt | 2 +-
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/test/java/examples/simple/PersonMapperTest.java b/src/test/java/examples/simple/PersonMapperTest.java
index ca1e90792..b50e38183 100644
--- a/src/test/java/examples/simple/PersonMapperTest.java
+++ b/src/test/java/examples/simple/PersonMapperTest.java
@@ -957,6 +957,6 @@ void gh737() {
"where id = #{parameters.p2,jdbcType=INTEGER}";
assertThat(updateStatement.getUpdateStatement()).isEqualTo(expected);
- assertThat(updateStatement.getParameters()).containsExactly(entry("p1", 4), entry("p2", 5));
+ assertThat(updateStatement.getParameters()).containsOnly(entry("p1", 4), entry("p2", 5));
}
}
diff --git a/src/test/java/examples/type_conversion/TypeConversionTest.java b/src/test/java/examples/type_conversion/TypeConversionTest.java
index 90846166e..017014508 100644
--- a/src/test/java/examples/type_conversion/TypeConversionTest.java
+++ b/src/test/java/examples/type_conversion/TypeConversionTest.java
@@ -93,7 +93,7 @@ void testFunctionInSelect() {
.render(RenderingStrategies.MYBATIS3);
Map row = mapper.selectOneMappedRow(selectStatement);
- assertThat(row).containsExactly(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
+ assertThat(row).containsOnly(entry("FILE_ID", 1), entry("FILE_CONTENTS", randomBlob));
selectStatement = select(fileId, toBase64(fileContents).as("checksum"))
.from(myfiles)
diff --git a/src/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java b/src/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java
index c3f8a5dea..2074b1cc4 100644
--- a/src/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java
+++ b/src/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java
@@ -41,6 +41,6 @@ void testWhereFragmentCollectorMerge() {
fc1.merge(fc2);
assertThat(fc1.collectFragments(Collectors.joining(","))).isEqualTo(":p1,:p2");
- assertThat(fc1.parameters()).containsExactly(entry("p1", 1), entry("p2", 2));
+ assertThat(fc1.parameters()).containsOnly(entry("p1", 1), entry("p2", 2));
}
}
diff --git a/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java b/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java
index 48bd36755..6ebf93049 100644
--- a/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java
+++ b/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java
@@ -143,7 +143,7 @@ void testOverrideFirstConnector() {
.render(RenderingStrategies.SPRING_NAMED_PARAMETER);
assertThat(whereClause).hasValueSatisfying(wc -> {
- assertThat(wc.getParameters()).containsExactly(entry("p1", "fred"), entry("p2", "flintstone"));
+ assertThat(wc.getParameters()).containsOnly(entry("p1", "fred"), entry("p2", "flintstone"));
assertThat(wc.getWhereClause()).isEqualTo("where first_name = :p1 or last_name = :p2");
});
}
@@ -185,7 +185,7 @@ void testWhereExistsOr() {
"or exists (select * from person where id = :p2)";
assertThat(whereClause).hasValueSatisfying(wc -> {
- assertThat(wc.getParameters()).containsExactly(entry("p1", 3), entry("p2", 4));
+ assertThat(wc.getParameters()).containsOnly(entry("p1", 3), entry("p2", 4));
assertThat(wc.getWhereClause()).isEqualTo(expected);
});
}
@@ -217,7 +217,7 @@ void testWhereExistsOrOr() {
"or exists (select * from person where id = :p3))";
assertThat(whereClause).hasValueSatisfying(wc -> {
- assertThat(wc.getParameters()).containsExactly(entry("p1", 3), entry("p2", 4), entry("p3", 5));
+ assertThat(wc.getParameters()).containsOnly(entry("p1", 3), entry("p2", 4), entry("p3", 5));
assertThat(wc.getWhereClause()).isEqualTo(expected);
});
}
@@ -242,7 +242,7 @@ void testWhereExistsAnd() {
"and exists (select * from person where id = :p2)";
assertThat(whereClause).hasValueSatisfying(wc -> {
- assertThat(wc.getParameters()).containsExactly(entry("p1", 3), entry("p2", 4));
+ assertThat(wc.getParameters()).containsOnly(entry("p1", 3), entry("p2", 4));
assertThat(wc.getWhereClause()).isEqualTo(expected);
});
}
@@ -274,7 +274,7 @@ void testWhereExistsAndAnd() {
"and exists (select * from person where id = :p3))";
assertThat(whereClause).hasValueSatisfying(wc -> {
- assertThat(wc.getParameters()).containsExactly(entry("p1", 3), entry("p2", 4), entry("p3", 5));
+ assertThat(wc.getParameters()).containsOnly(entry("p1", 3), entry("p2", 4), entry("p3", 5));
assertThat(wc.getWhereClause()).isEqualTo(expected);
});
}
@@ -315,7 +315,7 @@ void testCollapsingCriteriaGroup3() {
String expected = "where first_name = :p1 or first_name = :p2";
assertThat(whereClause).hasValueSatisfying(wc -> {
- assertThat(wc.getParameters()).containsExactly(entry("p1", "Fred"), entry("p2", "Betty"));
+ assertThat(wc.getParameters()).containsOnly(entry("p1", "Fred"), entry("p2", "Betty"));
assertThat(wc.getWhereClause()).isEqualTo(expected);
});
}
diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt
index 74c230200..e1403a0b0 100644
--- a/src/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt
+++ b/src/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt
@@ -672,6 +672,6 @@ open class KotlinElementsTest {
assertThat(updateStatement.updateStatement).isEqualTo(
"update Person set address_id = (address_id + :p1) where id = :p2"
)
- assertThat(updateStatement.parameters).containsExactly(entry("p1", 4), entry("p2", 5))
+ assertThat(updateStatement.parameters).containsOnly(entry("p1", 4), entry("p2", 5))
}
}
From 5c62e85a6a0516c5470bc0e54299e72b41bef694 Mon Sep 17 00:00:00 2001
From: Jeff Butler
Date: Tue, 7 Oct 2025 16:07:04 -0400
Subject: [PATCH 30/68] Update nullability specs
IntelliJ has fixed quite a few nullability inspection bugs - updating accordingly
---
.../sql/AbstractListValueCondition.java | 5 ++---
.../sql/AbstractSingleValueCondition.java | 5 ++---
.../sql/AbstractTwoValueCondition.java | 11 +++++------
.../org/mybatis/dynamic/sql/SqlBuilder.java | 13 ++++++-------
.../mybatis/dynamic/sql/util/Utilities.java | 10 ++++++++++
.../sql/where/condition/AndGatherer.java | 4 +---
.../sql/where/condition/IsBetween.java | 13 ++++++-------
.../where/condition/IsBetweenWhenPresent.java | 11 +++++------
.../sql/where/condition/IsEqualTo.java | 5 ++---
.../where/condition/IsEqualToWhenPresent.java | 5 ++---
.../sql/where/condition/IsGreaterThan.java | 5 ++---
.../condition/IsGreaterThanOrEqualTo.java | 5 ++---
.../IsGreaterThanOrEqualToWhenPresent.java | 5 ++---
.../condition/IsGreaterThanWhenPresent.java | 5 ++---
.../dynamic/sql/where/condition/IsIn.java | 5 ++---
.../where/condition/IsInCaseInsensitive.java | 5 ++---
.../IsInCaseInsensitiveWhenPresent.java | 5 ++---
.../sql/where/condition/IsInWhenPresent.java | 11 +++++------
.../sql/where/condition/IsLessThan.java | 5 ++---
.../where/condition/IsLessThanOrEqualTo.java | 5 ++---
.../IsLessThanOrEqualToWhenPresent.java | 5 ++---
.../condition/IsLessThanWhenPresent.java | 5 ++---
.../dynamic/sql/where/condition/IsLike.java | 5 ++---
.../condition/IsLikeCaseInsensitive.java | 5 ++---
.../IsLikeCaseInsensitiveWhenPresent.java | 5 ++---
.../where/condition/IsLikeWhenPresent.java | 5 ++---
.../sql/where/condition/IsNotBetween.java | 11 +++++------
.../condition/IsNotBetweenWhenPresent.java | 11 +++++------
.../sql/where/condition/IsNotEqualTo.java | 5 ++---
.../condition/IsNotEqualToWhenPresent.java | 5 ++---
.../dynamic/sql/where/condition/IsNotIn.java | 5 ++---
.../condition/IsNotInCaseInsensitive.java | 5 ++---
.../IsNotInCaseInsensitiveWhenPresent.java | 5 ++---
.../where/condition/IsNotInWhenPresent.java | 11 +++++------
.../sql/where/condition/IsNotLike.java | 5 ++---
.../condition/IsNotLikeCaseInsensitive.java | 5 ++---
.../IsNotLikeCaseInsensitiveWhenPresent.java | 5 ++---
.../where/condition/IsNotLikeWhenPresent.java | 5 ++---
.../array/NamesTableDynamicSqlSupport.java | 5 +++--
.../java/examples/array/package-info.java | 19 +++++++++++++++++++
.../ColumnComparisonConfiguration.java | 4 +++-
.../column/comparison/package-info.java | 19 +++++++++++++++++++
.../examples/complexquery/package-info.java | 19 +++++++++++++++++++
.../always/mybatis/package-info.java | 19 +++++++++++++++++++
.../generated/always/spring/package-info.java | 19 +++++++++++++++++++
.../java/examples/groupby/package-info.java | 19 +++++++++++++++++++
.../java/examples/mariadb/package-info.java | 19 +++++++++++++++++++
.../java/examples/postgres/package-info.java | 19 +++++++++++++++++++
.../springbatch/mapper/package-info.java | 19 +++++++++++++++++++
.../MyFilesDynamicSqlSupport.java | 5 +++--
.../examples/type_conversion/ToBase64.java | 5 +++--
src/test/java/issues/gh100/package-info.java | 19 +++++++++++++++++++
src/test/java/issues/gh105/package-info.java | 19 +++++++++++++++++++
.../java/issues/gh324/ObservableCache.java | 3 ++-
src/test/java/issues/gh324/package-info.java | 19 +++++++++++++++++++
src/test/java/issues/lhg142/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/delete/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/insert/package-info.java | 19 +++++++++++++++++++
.../sql/insert/render/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/mybatis3/package-info.java | 19 +++++++++++++++++++
.../org/mybatis/dynamic/sql/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/select/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/subselect/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/update/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/util/package-info.java | 19 +++++++++++++++++++
.../sql/where/condition/package-info.java | 19 +++++++++++++++++++
.../dynamic/sql/where/package-info.java | 19 +++++++++++++++++++
.../sql/where/render/package-info.java | 19 +++++++++++++++++++
.../kotlin/mybatis3/mariadb/KIsLikeEscape.kt | 2 +-
69 files changed, 599 insertions(+), 146 deletions(-)
create mode 100644 src/test/java/examples/array/package-info.java
create mode 100644 src/test/java/examples/column/comparison/package-info.java
create mode 100644 src/test/java/examples/complexquery/package-info.java
create mode 100644 src/test/java/examples/generated/always/mybatis/package-info.java
create mode 100644 src/test/java/examples/generated/always/spring/package-info.java
create mode 100644 src/test/java/examples/groupby/package-info.java
create mode 100644 src/test/java/examples/mariadb/package-info.java
create mode 100644 src/test/java/examples/postgres/package-info.java
create mode 100644 src/test/java/examples/springbatch/mapper/package-info.java
create mode 100644 src/test/java/issues/gh100/package-info.java
create mode 100644 src/test/java/issues/gh105/package-info.java
create mode 100644 src/test/java/issues/gh324/package-info.java
create mode 100644 src/test/java/issues/lhg142/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/delete/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/insert/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/insert/render/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/mybatis3/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/select/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/subselect/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/update/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/util/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/where/condition/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/where/package-info.java
create mode 100644 src/test/java/org/mybatis/dynamic/sql/where/render/package-info.java
diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java
index e178c6bf3..41c6a56e2 100644
--- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java
+++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java
@@ -23,7 +23,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.jspecify.annotations.NonNull;
import org.mybatis.dynamic.sql.render.RenderedParameterInfo;
import org.mybatis.dynamic.sql.render.RenderingContext;
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
@@ -114,7 +113,7 @@ public interface Filterable {
* @return this condition if renderable and the value matches the predicate, otherwise a condition
* that will not render.
*/
- AbstractListValueCondition filter(Predicate super @NonNull T> predicate);
+ AbstractListValueCondition filter(Predicate super T> predicate);
}
/**
@@ -139,6 +138,6 @@ public interface Mappable {
* @return a new condition with the result of applying the mapper to the value of this condition,
* if renderable, otherwise a condition that will not render.
*/
- AbstractListValueCondition map(Function super @NonNull T, ? extends R> mapper);
+ AbstractListValueCondition map(Function super T, ? extends R> mapper);
}
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java
index eb56eef39..c16dbf08c 100644
--- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java
+++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java
@@ -21,7 +21,6 @@
import java.util.function.Predicate;
import java.util.function.Supplier;
-import org.jspecify.annotations.NonNull;
import org.mybatis.dynamic.sql.render.RenderedParameterInfo;
import org.mybatis.dynamic.sql.render.RenderingContext;
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
@@ -89,7 +88,7 @@ public interface Filterable {
* @return this condition if renderable and the value matches the predicate, otherwise a condition
* that will not render.
*/
- AbstractSingleValueCondition filter(Predicate super @NonNull T> predicate);
+ AbstractSingleValueCondition filter(Predicate super T> predicate);
}
/**
@@ -114,6 +113,6 @@ public interface Mappable {
* @return a new condition with the result of applying the mapper to the value of this condition,
* if renderable, otherwise a condition that will not render.
*/
- AbstractSingleValueCondition map(Function super @NonNull T, ? extends R> mapper);
+ AbstractSingleValueCondition map(Function super T, ? extends R> mapper);
}
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java
index d409ffbb8..6cceff16e 100644
--- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java
+++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java
@@ -23,7 +23,6 @@
import java.util.function.Predicate;
import java.util.function.Supplier;
-import org.jspecify.annotations.NonNull;
import org.mybatis.dynamic.sql.render.RenderedParameterInfo;
import org.mybatis.dynamic.sql.render.RenderingContext;
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
@@ -111,7 +110,7 @@ public interface Filterable {
* @return this condition if renderable and the values match the predicate, otherwise a condition
* that will not render.
*/
- AbstractTwoValueCondition filter(BiPredicate super @NonNull T, ? super @NonNull T> predicate);
+ AbstractTwoValueCondition filter(BiPredicate super T, ? super T> predicate);
/**
* If renderable and both values match the predicate, returns this condition. Else returns a condition
@@ -122,7 +121,7 @@ public interface Filterable {
* @return this condition if renderable and the values match the predicate, otherwise a condition
* that will not render.
*/
- AbstractTwoValueCondition filter(Predicate super @NonNull T> predicate);
+ AbstractTwoValueCondition filter(Predicate super T> predicate);
}
/**
@@ -148,8 +147,8 @@ public interface Mappable {
* @return a new condition with the result of applying the mappers to the values of this condition,
* if renderable, otherwise a condition that will not render.
*/
- AbstractTwoValueCondition map(Function super @NonNull T, ? extends R> mapper1,
- Function super @NonNull T, ? extends R> mapper2);
+ AbstractTwoValueCondition map(Function super T, ? extends R> mapper1,
+ Function super T, ? extends R> mapper2);
/**
* If renderable, apply the mapping to both values and return a new condition with the new values. Else return a
@@ -160,6 +159,6 @@ AbstractTwoValueCondition map(Function super @NonNull T, ? extends R> m
* @return a new condition with the result of applying the mappers to the values of this condition,
* if renderable, otherwise a condition that will not render.
*/
- AbstractTwoValueCondition map(Function super @NonNull T, ? extends R> mapper);
+ AbstractTwoValueCondition map(Function super T, ? extends R> mapper);
}
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java
index c8fe5c3ba..2a8243999 100644
--- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java
+++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java
@@ -21,7 +21,6 @@
import java.util.Objects;
import java.util.function.Supplier;
-import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.mybatis.dynamic.sql.delete.DeleteDSL;
import org.mybatis.dynamic.sql.delete.DeleteModel;
@@ -782,11 +781,11 @@ static IsLessThanOrEqualToWhenPresent isLessThanOrEqualToWhenPresent(Supp
}
@SafeVarargs
- static IsIn isIn(@NonNull T... values) {
+ static IsIn isIn(T... values) {
return IsIn.of(values);
}
- static IsIn isIn(Collection<@NonNull T> values) {
+ static IsIn isIn(Collection values) {
return IsIn.of(values);
}
@@ -804,11 +803,11 @@ static IsInWhenPresent isInWhenPresent(@Nullable Collection<@Nullable T>
}
@SafeVarargs
- static IsNotIn isNotIn(@NonNull T... values) {
+ static IsNotIn isNotIn(T... values) {
return IsNotIn.of(values);
}
- static IsNotIn isNotIn(Collection<@NonNull T> values) {
+ static IsNotIn isNotIn(Collection values) {
return IsNotIn.of(values);
}
@@ -829,7 +828,7 @@ static IsBetween.Builder isBetween(T value1) {
return IsBetween.isBetween(value1);
}
- static IsBetween.Builder isBetween(Supplier<@NonNull T> valueSupplier1) {
+ static IsBetween.Builder isBetween(Supplier valueSupplier1) {
return isBetween(valueSupplier1.get());
}
@@ -845,7 +844,7 @@ static IsNotBetween.Builder isNotBetween(T value1) {
return IsNotBetween.isNotBetween(value1);
}
- static IsNotBetween.Builder isNotBetween(Supplier<@NonNull T> valueSupplier1) {
+ static IsNotBetween.Builder isNotBetween(Supplier valueSupplier1) {
return isNotBetween(valueSupplier1.get());
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java
index 0c3bd188f..507d873c9 100644
--- a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java
+++ b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java
@@ -15,10 +15,20 @@
*/
package org.mybatis.dynamic.sql.util;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.stream.Stream;
+
import org.jspecify.annotations.Nullable;
public interface Utilities {
static long safelyUnbox(@Nullable Long l) {
return l == null ? 0 : l;
}
+
+ static Collection filterNulls(Collection<@Nullable T> values) {
+ // this method helps IntelliJ understand intended nullability
+ Stream st = values.stream().filter(Objects::nonNull);
+ return st.toList();
+ }
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java
index c9514f3fa..8a587262a 100644
--- a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java
+++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java
@@ -17,8 +17,6 @@
import java.util.function.Supplier;
-import org.jspecify.annotations.NonNull;
-
/**
* Utility class supporting the "and" part of a between condition. This class supports builders, so it is mutable.
*
@@ -40,7 +38,7 @@ public R and(T value2) {
return build(value2);
}
- public R and(Supplier<@NonNull T> valueSupplier2) {
+ public R and(Supplier valueSupplier2) {
return and(valueSupplier2.get());
}
diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java
index 0f7fcd66a..ffc801508 100644
--- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java
+++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java
@@ -20,10 +20,9 @@
import java.util.function.Function;
import java.util.function.Predicate;
-import org.jspecify.annotations.NonNull;
import org.mybatis.dynamic.sql.AbstractTwoValueCondition;
-public class IsBetween extends AbstractTwoValueCondition<@NonNull T>
+public class IsBetween extends AbstractTwoValueCondition
implements AbstractTwoValueCondition.Filterable, AbstractTwoValueCondition.Mappable {
private static final IsBetween> EMPTY = new IsBetween