Skip to content

Commit 7341365

Browse files
authored
Merge pull request #969 from jeffgbutler/gh-964
Add Ability to configure a mapped Java property in an SqlColumn
2 parents b0e1d19 + 997a11b commit 7341365

31 files changed

+510
-76
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ Runtime behavior changes:
107107
are not supported by the library out of the box. The statement renderers now call methods `renderCondition` and
108108
`renderLeftColumn` that you can override to implement any rendering you need. In addition, we've made `filter` and
109109
`map` support optional if you implement custom conditions
110+
- Added support for configuring a Java property name to be associated with an `SqlColumn`. This property name can be
111+
used with the record based insert methods to reduce the boilerplate code for mapping columns to Java properties.
110112

111113
## Release 1.5.2 - June 3, 2024
112114

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class SqlColumn<T> implements BindableColumn<T>, SortSpecification {
3737
protected final ParameterTypeConverter<T, ?> parameterTypeConverter;
3838
protected final @Nullable String tableQualifier;
3939
protected final @Nullable Class<T> javaType;
40+
protected final @Nullable String javaProperty;
4041

4142
private SqlColumn(Builder<T> builder) {
4243
name = Objects.requireNonNull(builder.name);
@@ -49,6 +50,7 @@ private SqlColumn(Builder<T> builder) {
4950
parameterTypeConverter = Objects.requireNonNull(builder.parameterTypeConverter);
5051
tableQualifier = builder.tableQualifier;
5152
javaType = builder.javaType;
53+
javaProperty = builder.javaProperty;
5254
}
5355

5456
public String name() {
@@ -79,6 +81,10 @@ public Optional<Class<T>> javaType() {
7981
return Optional.ofNullable(javaType);
8082
}
8183

84+
public Optional<String> javaProperty() {
85+
return Optional.ofNullable(javaProperty);
86+
}
87+
8288
@Override
8389
public @Nullable Object convertParameterType(@Nullable T value) {
8490
return value == null ? null : parameterTypeConverter.convert(value);
@@ -164,6 +170,11 @@ public <S> SqlColumn<S> withJavaType(Class<S> javaType) {
164170
return b.withJavaType(javaType).build();
165171
}
166172

173+
public <S> SqlColumn<S> withJavaProperty(String javaProperty) {
174+
Builder<S> b = copy();
175+
return b.withJavaProperty(javaProperty).build();
176+
}
177+
167178
/**
168179
* This method helps us tell a bit of fiction to the Java compiler. Java, for better or worse,
169180
* does not carry generic type information through chained methods. We want to enable method
@@ -185,7 +196,8 @@ private <S> Builder<S> copy() {
185196
.withRenderingStrategy(this.renderingStrategy)
186197
.withParameterTypeConverter((ParameterTypeConverter<S, ?>) this.parameterTypeConverter)
187198
.withTableQualifier(this.tableQualifier)
188-
.withJavaType((Class<S>) this.javaType);
199+
.withJavaType((Class<S>) this.javaType)
200+
.withJavaProperty(this.javaProperty);
189201
}
190202

191203
public static <T> SqlColumn<T> of(String name, SqlTable table) {
@@ -212,6 +224,7 @@ public static class Builder<T> {
212224
protected ParameterTypeConverter<T, ?> parameterTypeConverter = v -> v;
213225
protected @Nullable String tableQualifier;
214226
protected @Nullable Class<T> javaType;
227+
protected @Nullable String javaProperty;
215228

216229
public Builder<T> withName(String name) {
217230
this.name = name;
@@ -263,6 +276,11 @@ public Builder<T> withJavaType(@Nullable Class<T> javaType) {
263276
return this;
264277
}
265278

279+
public Builder<T> withJavaProperty(@Nullable String javaProperty) {
280+
this.javaProperty = javaProperty;
281+
return this;
282+
}
283+
266284
public SqlColumn<T> build() {
267285
return new SqlColumn<>(this);
268286
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.mybatis.dynamic.sql.util.AbstractColumnMapping;
2828
import org.mybatis.dynamic.sql.util.Buildable;
2929
import org.mybatis.dynamic.sql.util.ConstantMapping;
30+
import org.mybatis.dynamic.sql.util.MappedColumnMapping;
3031
import org.mybatis.dynamic.sql.util.NullMapping;
3132
import org.mybatis.dynamic.sql.util.PropertyMapping;
3233
import org.mybatis.dynamic.sql.util.RowMapping;
@@ -48,6 +49,11 @@ public <F> ColumnMappingFinisher<F> map(SqlColumn<F> column) {
4849
return new ColumnMappingFinisher<>(column);
4950
}
5051

52+
public <F> BatchInsertDSL<T> withMappedColumn(SqlColumn<F> column) {
53+
columnMappings.add(MappedColumnMapping.of(column));
54+
return this;
55+
}
56+
5157
@Override
5258
public BatchInsertModel<T> build() {
5359
return BatchInsertModel.withRecords(records)

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.mybatis.dynamic.sql.util.AbstractColumnMapping;
2828
import org.mybatis.dynamic.sql.util.Buildable;
2929
import org.mybatis.dynamic.sql.util.ConstantMapping;
30+
import org.mybatis.dynamic.sql.util.MappedColumnMapping;
31+
import org.mybatis.dynamic.sql.util.MappedColumnWhenPresentMapping;
3032
import org.mybatis.dynamic.sql.util.NullMapping;
3133
import org.mybatis.dynamic.sql.util.PropertyMapping;
3234
import org.mybatis.dynamic.sql.util.PropertyWhenPresentMapping;
@@ -49,6 +51,16 @@ public <F> ColumnMappingFinisher<F> map(SqlColumn<F> column) {
4951
return new ColumnMappingFinisher<>(column);
5052
}
5153

54+
public <F> InsertDSL<T> withMappedColumn(SqlColumn<F> column) {
55+
columnMappings.add(MappedColumnMapping.of(column));
56+
return this;
57+
}
58+
59+
public <F> InsertDSL<T> withMappedColumnWhenPresent(SqlColumn<F> column, Supplier<?> valueSupplier) {
60+
columnMappings.add(MappedColumnWhenPresentMapping.of(column, valueSupplier));
61+
return this;
62+
}
63+
5264
@Override
5365
public InsertModel<T> build() {
5466
return InsertModel.withRow(row)

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.mybatis.dynamic.sql.util.AbstractColumnMapping;
2626
import org.mybatis.dynamic.sql.util.Buildable;
2727
import org.mybatis.dynamic.sql.util.ConstantMapping;
28+
import org.mybatis.dynamic.sql.util.MappedColumnMapping;
2829
import org.mybatis.dynamic.sql.util.NullMapping;
2930
import org.mybatis.dynamic.sql.util.PropertyMapping;
3031
import org.mybatis.dynamic.sql.util.RowMapping;
@@ -46,6 +47,11 @@ public <F> ColumnMappingFinisher<F> map(SqlColumn<F> column) {
4647
return new ColumnMappingFinisher<>(column);
4748
}
4849

50+
public <F> MultiRowInsertDSL<T> withMappedColumn(SqlColumn<F> column) {
51+
columnMappings.add(MappedColumnMapping.of(column));
52+
return this;
53+
}
54+
4955
@Override
5056
public MultiRowInsertModel<T> build() {
5157
return MultiRowInsertModel.withRecords(records)

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore;
1919

20+
import org.mybatis.dynamic.sql.SqlColumn;
2021
import org.mybatis.dynamic.sql.SqlTable;
22+
import org.mybatis.dynamic.sql.exception.InvalidSqlException;
23+
import org.mybatis.dynamic.sql.util.Messages;
2124

2225
public class InsertRenderingUtilities {
2326
private InsertRenderingUtilities() {}
@@ -33,4 +36,10 @@ public static String calculateInsertStatement(SqlTable table, FieldAndValueColle
3336
public static String calculateInsertStatementStart(SqlTable table) {
3437
return "insert into " + table.tableName(); //$NON-NLS-1$
3538
}
39+
40+
public static String getMappedPropertyName(SqlColumn<?> column) {
41+
return column.javaProperty().orElseThrow(() ->
42+
new InvalidSqlException(Messages
43+
.getString("ERROR.50", column.name()))); //$NON-NLS-1$
44+
}
3645
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.mybatis.dynamic.sql.SqlColumn;
1919
import org.mybatis.dynamic.sql.render.RenderingStrategy;
2020
import org.mybatis.dynamic.sql.util.ConstantMapping;
21+
import org.mybatis.dynamic.sql.util.MappedColumnMapping;
2122
import org.mybatis.dynamic.sql.util.MultiRowInsertMappingVisitor;
2223
import org.mybatis.dynamic.sql.util.NullMapping;
2324
import org.mybatis.dynamic.sql.util.PropertyMapping;
@@ -69,6 +70,16 @@ public FieldAndValueAndParameters visit(RowMapping mapping) {
6970
.build();
7071
}
7172

73+
@Override
74+
public FieldAndValueAndParameters visit(MappedColumnMapping mapping) {
75+
return FieldAndValueAndParameters.withFieldName(mapping.columnName())
76+
.withValuePhrase(calculateJdbcPlaceholder(
77+
mapping.column(),
78+
InsertRenderingUtilities.getMappedPropertyName(mapping.column()))
79+
)
80+
.build();
81+
}
82+
7283
private String calculateJdbcPlaceholder(SqlColumn<?> column) {
7384
return column.renderingStrategy().orElse(renderingStrategy).getRecordBasedInsertBinding(column, prefix);
7485
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import org.mybatis.dynamic.sql.render.RenderingStrategy;
2222
import org.mybatis.dynamic.sql.util.ConstantMapping;
2323
import org.mybatis.dynamic.sql.util.InsertMappingVisitor;
24+
import org.mybatis.dynamic.sql.util.MappedColumnMapping;
25+
import org.mybatis.dynamic.sql.util.MappedColumnWhenPresentMapping;
2426
import org.mybatis.dynamic.sql.util.NullMapping;
2527
import org.mybatis.dynamic.sql.util.PropertyMapping;
2628
import org.mybatis.dynamic.sql.util.PropertyWhenPresentMapping;
@@ -80,6 +82,25 @@ public Optional<FieldAndValueAndParameters> visit(RowMapping mapping) {
8082
.buildOptional();
8183
}
8284

85+
@Override
86+
public Optional<FieldAndValueAndParameters> visit(MappedColumnMapping mapping) {
87+
return FieldAndValueAndParameters.withFieldName(mapping.columnName())
88+
.withValuePhrase(calculateJdbcPlaceholder(
89+
mapping.column(),
90+
InsertRenderingUtilities.getMappedPropertyName(mapping.column()))
91+
)
92+
.buildOptional();
93+
}
94+
95+
@Override
96+
public Optional<FieldAndValueAndParameters> visit(MappedColumnWhenPresentMapping mapping) {
97+
if (mapping.shouldRender()) {
98+
return visit((MappedColumnMapping) mapping);
99+
} else {
100+
return Optional.empty();
101+
}
102+
}
103+
83104
private String calculateJdbcPlaceholder(SqlColumn<?> column) {
84105
return column.renderingStrategy().orElse(renderingStrategy)
85106
.getRecordBasedInsertBinding(column, "row"); //$NON-NLS-1$

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,8 @@ public interface ColumnMappingVisitor<R> {
5252
R visit(ColumnToColumnMapping mapping);
5353

5454
R visit(RowMapping mapping);
55+
56+
R visit(MappedColumnMapping mapping);
57+
58+
R visit(MappedColumnWhenPresentMapping mapping);
5559
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,14 @@ public final R visit(ColumnToColumnMapping columnMapping) {
4040
public final R visit(RowMapping mapping) {
4141
throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_14));
4242
}
43+
44+
@Override
45+
public R visit(MappedColumnMapping mapping) {
46+
throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_16));
47+
}
48+
49+
@Override
50+
public R visit(MappedColumnWhenPresentMapping mapping) {
51+
throw new UnsupportedOperationException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_17));
52+
}
4353
}

0 commit comments

Comments
 (0)