Skip to content

Commit af417bd

Browse files
committed
Add ability to use a function in an update statement
This also removes the incrementBy, decrementBy, etc. operations as they are replaced by more flexible alternatives.
1 parent 549c458 commit af417bd

File tree

13 files changed

+326
-145
lines changed

13 files changed

+326
-145
lines changed

src/main/java/org/mybatis/dynamic/sql/select/function/Constant.java renamed to src/main/java/org/mybatis/dynamic/sql/Constant.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,19 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.mybatis.dynamic.sql.select.function;
16+
package org.mybatis.dynamic.sql;
1717

1818
import java.util.Objects;
1919
import java.util.Optional;
2020

21-
import org.mybatis.dynamic.sql.BasicColumn;
2221
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2322

24-
public class Constant<T> implements BasicColumn {
23+
public class Constant implements BasicColumn {
2524

2625
private String alias;
27-
private T value;
26+
private String value;
2827

29-
private Constant(T value) {
28+
private Constant(String value) {
3029
this.value = Objects.requireNonNull(value);
3130
}
3231

@@ -37,17 +36,17 @@ public Optional<String> alias() {
3736

3837
@Override
3938
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
40-
return value.toString();
39+
return value;
4140
}
4241

4342
@Override
44-
public Constant<T> as(String alias) {
45-
Constant<T> copy = new Constant<>(value);
43+
public Constant as(String alias) {
44+
Constant copy = new Constant(value);
4645
copy.alias = alias;
4746
return copy;
4847
}
4948

50-
public static <T> Constant<T> of(T value) {
51-
return new Constant<>(value);
49+
public static Constant of(String value) {
50+
return new Constant(value);
5251
}
5352
}

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.mybatis.dynamic.sql.select.aggregate.Min;
3636
import org.mybatis.dynamic.sql.select.aggregate.Sum;
3737
import org.mybatis.dynamic.sql.select.function.Add;
38-
import org.mybatis.dynamic.sql.select.function.Constant;
3938
import org.mybatis.dynamic.sql.select.function.Divide;
4039
import org.mybatis.dynamic.sql.select.function.Lower;
4140
import org.mybatis.dynamic.sql.select.function.Multiply;
@@ -192,12 +191,12 @@ static Sum sum(BasicColumn column) {
192191
}
193192

194193
// constants
195-
static <T extends Number> Constant<T> constant(T number) {
196-
return Constant.of(number);
194+
static Constant constant(String constant) {
195+
return Constant.of(constant);
197196
}
198197

199-
static Constant<String> constant(String string) {
200-
return Constant.of("'" + string + "'"); //$NON-NLS-1$ //$NON-NLS-2$
198+
static StringConstant stringConstant(String constant) {
199+
return StringConstant.of(constant);
201200
}
202201

203202
// functions
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Copyright 2016-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql;
17+
18+
import java.util.Objects;
19+
import java.util.Optional;
20+
21+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
22+
23+
public class StringConstant implements BasicColumn {
24+
25+
private String alias;
26+
private String value;
27+
28+
private StringConstant(String value) {
29+
this.value = Objects.requireNonNull(value);
30+
}
31+
32+
@Override
33+
public Optional<String> alias() {
34+
return Optional.ofNullable(alias);
35+
}
36+
37+
@Override
38+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
39+
return "'" + value + "'"; //$NON-NLS-1$ //$NON-NLS-2$
40+
}
41+
42+
@Override
43+
public StringConstant as(String alias) {
44+
StringConstant copy = new StringConstant(value);
45+
copy.alias = alias;
46+
return copy;
47+
}
48+
49+
public static StringConstant of(String value) {
50+
return new StringConstant(value);
51+
}
52+
}

src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@
2121
import java.util.function.Function;
2222
import java.util.function.Supplier;
2323

24+
import org.mybatis.dynamic.sql.BasicColumn;
2425
import org.mybatis.dynamic.sql.BindableColumn;
2526
import org.mybatis.dynamic.sql.SqlColumn;
2627
import org.mybatis.dynamic.sql.SqlCriterion;
2728
import org.mybatis.dynamic.sql.SqlTable;
2829
import org.mybatis.dynamic.sql.VisitableCondition;
2930
import org.mybatis.dynamic.sql.select.SelectModel;
3031
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
31-
import org.mybatis.dynamic.sql.util.ArithmeticConstantMapping;
32-
import org.mybatis.dynamic.sql.util.ArithmeticOperation;
3332
import org.mybatis.dynamic.sql.util.Buildable;
33+
import org.mybatis.dynamic.sql.util.ColumnMapping;
3434
import org.mybatis.dynamic.sql.util.ConstantMapping;
3535
import org.mybatis.dynamic.sql.util.NullMapping;
3636
import org.mybatis.dynamic.sql.util.SelectMapping;
@@ -126,6 +126,11 @@ public UpdateDSL<R> equalTo(Buildable<SelectModel> buildable) {
126126
return UpdateDSL.this;
127127
}
128128

129+
public UpdateDSL<R> equalTo(BasicColumn rightColumn) {
130+
columnMappings.add(ColumnMapping.of(column, rightColumn));
131+
return UpdateDSL.this;
132+
}
133+
129134
public UpdateDSL<R> equalToWhenPresent(T value) {
130135
return equalToWhenPresent(() -> value);
131136
}
@@ -136,42 +141,6 @@ public UpdateDSL<R> equalToWhenPresent(Supplier<T> valueSupplier) {
136141
}
137142
return UpdateDSL.this;
138143
}
139-
140-
public UpdateDSL<R> incrementBy(T value) {
141-
return incrementBy(() -> value);
142-
}
143-
144-
public UpdateDSL<R> incrementBy(Supplier<T> valueSupplier) {
145-
columnMappings.add(ArithmeticConstantMapping.of(column, ArithmeticOperation.ADD, valueSupplier));
146-
return UpdateDSL.this;
147-
}
148-
149-
public UpdateDSL<R> decrementBy(T value) {
150-
return decrementBy(() -> value);
151-
}
152-
153-
public UpdateDSL<R> decrementBy(Supplier<T> valueSupplier) {
154-
columnMappings.add(ArithmeticConstantMapping.of(column, ArithmeticOperation.SUBTRACT, valueSupplier));
155-
return UpdateDSL.this;
156-
}
157-
158-
public UpdateDSL<R> multiplyBy(T value) {
159-
return multiplyBy(() -> value);
160-
}
161-
162-
public UpdateDSL<R> multiplyBy(Supplier<T> valueSupplier) {
163-
columnMappings.add(ArithmeticConstantMapping.of(column, ArithmeticOperation.MULTIPLY, valueSupplier));
164-
return UpdateDSL.this;
165-
}
166-
167-
public UpdateDSL<R> divideBy(T value) {
168-
return divideBy(() -> value);
169-
}
170-
171-
public UpdateDSL<R> divideBy(Supplier<T> valueSupplier) {
172-
columnMappings.add(ArithmeticConstantMapping.of(column, ArithmeticOperation.DIVIDE, valueSupplier));
173-
return UpdateDSL.this;
174-
}
175144
}
176145

177146
public class UpdateWhereBuilder extends AbstractWhereDSL<UpdateWhereBuilder> {

src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121

2222
import org.mybatis.dynamic.sql.SqlColumn;
2323
import org.mybatis.dynamic.sql.render.RenderingStrategy;
24+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2425
import org.mybatis.dynamic.sql.select.render.SelectRenderer;
2526
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
26-
import org.mybatis.dynamic.sql.util.ArithmeticConstantMapping;
27+
import org.mybatis.dynamic.sql.util.ColumnMapping;
2728
import org.mybatis.dynamic.sql.util.ConstantMapping;
2829
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
2930
import org.mybatis.dynamic.sql.util.NullMapping;
@@ -80,19 +81,6 @@ public <T> FragmentAndParameters visit(ValueMapping<T> mapping) {
8081
.build();
8182
}
8283

83-
@Override
84-
public <S> FragmentAndParameters visit(ArithmeticConstantMapping<S> mapping) {
85-
String fragment = mapping.mapColumn(SqlColumn::name)
86-
+ " = " //$NON-NLS-1$
87-
+ mapping.mapColumn(SqlColumn::name)
88-
+ " " //$NON-NLS-1$
89-
+ mapping.operation().getOperator()
90-
+ " " //$NON-NLS-1$
91-
+ mapping.valueSupplier().get();
92-
return FragmentAndParameters.withFragment(fragment)
93-
.build();
94-
}
95-
9684
@Override
9785
public FragmentAndParameters visit(SelectMapping mapping) {
9886
SelectStatementProvider selectStatement = SelectRenderer.withSelectModel(mapping.selectModel())
@@ -111,6 +99,16 @@ public FragmentAndParameters visit(SelectMapping mapping) {
11199
.build();
112100
}
113101

102+
@Override
103+
public FragmentAndParameters visit(ColumnMapping mapping) {
104+
String setPhrase = mapping.mapColumn(SqlColumn::name)
105+
+ " = " //$NON-NLS-1$
106+
+ mapping.rightColumn().renderWithTableAlias(TableAliasCalculator.empty());
107+
108+
return FragmentAndParameters.withFragment(setPhrase)
109+
.build();
110+
}
111+
114112
private Function<SqlColumn<?>, String> toJdbcPlaceholder(String parameterName) {
115113
return column -> renderingStrategy
116114
.getFormattedJdbcPlaceholder(column, "parameters", parameterName); //$NON-NLS-1$

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

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/main/java/org/mybatis/dynamic/sql/util/ArithmeticOperation.java renamed to src/main/java/org/mybatis/dynamic/sql/util/ColumnMapping.java

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

18-
public enum ArithmeticOperation {
19-
ADD("+"), //$NON-NLS-1$
20-
SUBTRACT("-"), //$NON-NLS-1$
21-
MULTIPLY("*"), //$NON-NLS-1$
22-
DIVIDE("/"); //$NON-NLS-1$
18+
import org.mybatis.dynamic.sql.BasicColumn;
19+
import org.mybatis.dynamic.sql.SqlColumn;
20+
21+
public class ColumnMapping extends AbstractColumnMapping implements UpdateMapping {
22+
23+
private BasicColumn rightColumn;
2324

24-
private String operator;
25+
private ColumnMapping(SqlColumn<?> column, BasicColumn rightColumn) {
26+
super(column);
27+
this.rightColumn = rightColumn;
28+
}
2529

26-
private ArithmeticOperation(String operator) {
27-
this.operator = operator;
30+
public BasicColumn rightColumn() {
31+
return rightColumn;
2832
}
2933

30-
public String getOperator() {
31-
return operator;
34+
@Override
35+
public <R> R accept(UpdateMappingVisitor<R> visitor) {
36+
return visitor.visit(this);
37+
}
38+
39+
public static ColumnMapping of(SqlColumn<?> column, BasicColumn rightColumn) {
40+
return new ColumnMapping(column, rightColumn);
3241
}
3342
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public interface UpdateMappingVisitor<T> {
2424

2525
<S> T visit(ValueMapping<S> mapping);
2626

27-
<S> T visit(ArithmeticConstantMapping<S> mapping);
28-
2927
T visit(SelectMapping mapping);
28+
29+
T visit(ColumnMapping columnMapping);
3030
}

src/site/markdown/docs/update.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Notice the `set` method. It is used to set the value of a database column. Ther
2525
6. `set(column).equalToWhenPresent(T value)` will set a value 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" update as defined in MyBatis Generator.
2626
7. `set(column).equalToWhenPresent(Supplier<T> valueSupplier)` will set a value 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" update as defined in MyBatis Generator.
2727
8. `set(column).equalTo(Buildable<SelectModel> selectModelBuilder)` will set the result of a sub-query into a column. The query should only have one column and the type of the returned column must be able to be converted by the database if it is not the same type. These constraints are NOT validated by the library.
28+
9. `set(column).equalTo(BasicColumn rightColumn)` will set the value of a column the be the value of another column. This is also useful for specifying a function such as add, subtract, etc.
2829

2930
You can also build an update statement without a where clause. This will update every row in a table.
3031
For example:

src/test/java/examples/animal/data/AnimalDataMapper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2017 the original author or authors.
2+
* Copyright 2016-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,6 +46,10 @@ public interface AnimalDataMapper {
4646
})
4747
List<AnimalData> selectMany(SelectStatementProvider selectStatement);
4848

49+
@SelectProvider(type=SqlProviderAdapter.class, method="select")
50+
@ResultMap("AnimalDataResult")
51+
AnimalData selectOne(SelectStatementProvider selectStatement);
52+
4953
@SelectProvider(type=SqlProviderAdapter.class, method="select")
5054
List<Map<String, Object>> generalSelect(SelectStatementProvider selectStatement);
5155

0 commit comments

Comments
 (0)