Skip to content

Commit 19f1dd0

Browse files
authored
Merge pull request #121 from jeffgbutler/update-by-example-improvement
UpdateByExample Support Improvement
2 parents 9b8c5eb + a6e9d06 commit 19f1dd0

8 files changed

+253
-46
lines changed

src/main/java/org/mybatis/dynamic/sql/util/mybatis3/MyBatis3CountByExampleHelper.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,30 @@
4747
* q.where(occupation, isNull()));
4848
* </pre>
4949
*
50-
* <p>You can also do a "count all" with the following code:
50+
* <p>You can implement a "count all" with the following code:
5151
*
5252
* <pre>
5353
* long rows = mapper.countByExample(q -&gt; q);
5454
* </pre>
55+
*
56+
* <p>Or
57+
*
58+
* <pre>
59+
* long rows = mapper.countByExample(MyBatis3CountByExampleHelper.allRows());
60+
* </pre>
5561
*
5662
* @author Jeff Butler
5763
*/
5864
@FunctionalInterface
5965
public interface MyBatis3CountByExampleHelper extends
6066
Function<QueryExpressionDSL<MyBatis3SelectModelAdapter<Long>>, Buildable<MyBatis3SelectModelAdapter<Long>>> {
67+
68+
/**
69+
* Returns a helper that can be used to count every row in a table.
70+
*
71+
* @return the helper that will count every row in a table
72+
*/
73+
static MyBatis3CountByExampleHelper allRows() {
74+
return h -> h;
75+
}
6176
}

src/main/java/org/mybatis/dynamic/sql/util/mybatis3/MyBatis3DeleteByExampleHelper.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,30 @@
4646
* q.where(occupation, isNull()));
4747
* </pre>
4848
*
49-
* <p>You can also do a "delete all" with the following code:
49+
* <p>You can implement a "delete all" with the following code:
5050
*
5151
* <pre>
5252
* int rows = mapper.deleteByExample(q -&gt; q);
5353
* </pre>
5454
*
55+
* <p>Or
56+
*
57+
* <pre>
58+
* long rows = mapper.deleteByExample(MyBatis3DeleteByExampleHelper.allRows());
59+
* </pre>
60+
5561
* @author Jeff Butler
5662
*/
5763
@FunctionalInterface
5864
public interface MyBatis3DeleteByExampleHelper extends
5965
Function<DeleteDSL<MyBatis3DeleteModelAdapter<Integer>>, Buildable<MyBatis3DeleteModelAdapter<Integer>>> {
66+
67+
/**
68+
* Returns a helper that can be used to delete every row in a table.
69+
*
70+
* @return the helper that will delete every row in a table
71+
*/
72+
static MyBatis3DeleteByExampleHelper allRows() {
73+
return h -> h;
74+
}
6075
}

src/main/java/org/mybatis/dynamic/sql/util/mybatis3/MyBatis3SelectByExampleHelper.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,33 @@
5757
* .or(occupation, isNull()));
5858
* </pre>
5959
*
60-
* <p>You can also do a "select all" with the following code:
60+
* <p>You can implement a "select all" with the following code:
6161
*
6262
* <pre>
6363
* List&lt;SimpleRecord&gt; rows = mapper.selectByExample(q -&gt; q);
6464
* </pre>
6565
*
66+
* <p>Or
67+
*
68+
* <pre>
69+
* List&lt;SimpleRecord&gt; rows = mapper.selectByExample(MyBatis3SelectByExampleHelper.allRows());
70+
* </pre>
71+
*
6672
* @author Jeff Butler
6773
*/
6874
@FunctionalInterface
6975
public interface MyBatis3SelectByExampleHelper<T> extends
7076
Function<QueryExpressionDSL<MyBatis3SelectModelAdapter<List<T>>>,
7177
Buildable<MyBatis3SelectModelAdapter<List<T>>>> {
78+
79+
/**
80+
* Returns a helper that can be used to select every row in a table.
81+
*
82+
* @param <T> the type of row returned
83+
*
84+
* @return the helper that will select every row in a table
85+
*/
86+
static <T> MyBatis3SelectByExampleHelper<T> allRows() {
87+
return h -> h;
88+
}
7289
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Copyright 2016-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.util.mybatis3;
17+
18+
import java.util.Objects;
19+
import java.util.function.ToIntFunction;
20+
21+
import org.mybatis.dynamic.sql.SqlTable;
22+
import org.mybatis.dynamic.sql.update.UpdateDSL;
23+
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
24+
25+
/**
26+
* This class is used to complete an update by example method in the style of MyBatis generator.
27+
*
28+
* @author Jeff Butler
29+
*
30+
* @see MyBatis3UpdateByExampleHelper
31+
*
32+
* @param <T> the type of record that will be updated
33+
*/
34+
public class MyBatis3UpdateByExampleCompleter<T> {
35+
private SqlTable table;
36+
private MyBatis3UpdateByExampleHelper helper;
37+
private ToIntFunction<UpdateStatementProvider> mapper;
38+
private MyBatis3UpdateByExampleValueSetter<T> valueSetter;
39+
40+
private MyBatis3UpdateByExampleCompleter(MyBatis3UpdateByExampleCompleter.Builder<T> builder) {
41+
helper = Objects.requireNonNull(builder.helper);
42+
mapper = Objects.requireNonNull(builder.mapper);
43+
valueSetter = Objects.requireNonNull(builder.valueSetter);
44+
table = Objects.requireNonNull(builder.table);
45+
}
46+
47+
public int usingRecord(T record) {
48+
return valueSetter.andThen(helper)
49+
.apply(record, UpdateDSL.updateWithMapper(p -> mapper.applyAsInt(p), table))
50+
.build()
51+
.execute();
52+
}
53+
54+
public static class Builder<T> {
55+
private SqlTable table;
56+
private MyBatis3UpdateByExampleHelper helper;
57+
private ToIntFunction<UpdateStatementProvider> mapper;
58+
private MyBatis3UpdateByExampleValueSetter<T> valueSetter;
59+
60+
public MyBatis3UpdateByExampleCompleter.Builder<T> withTable(SqlTable table) {
61+
this.table = table;
62+
return this;
63+
}
64+
65+
public MyBatis3UpdateByExampleCompleter.Builder<T> withHelper(MyBatis3UpdateByExampleHelper helper) {
66+
this.helper = helper;
67+
return this;
68+
}
69+
70+
public MyBatis3UpdateByExampleCompleter.Builder<T> withMapper(
71+
ToIntFunction<UpdateStatementProvider> mapper) {
72+
this.mapper = mapper;
73+
return this;
74+
}
75+
76+
public MyBatis3UpdateByExampleCompleter.Builder<T> withValueSetter(
77+
MyBatis3UpdateByExampleValueSetter<T> valueSetter) {
78+
this.valueSetter = valueSetter;
79+
return this;
80+
}
81+
82+
public MyBatis3UpdateByExampleCompleter<T> build() {
83+
return new MyBatis3UpdateByExampleCompleter<>(this);
84+
}
85+
}
86+
}

src/main/java/org/mybatis/dynamic/sql/util/mybatis3/MyBatis3UpdateByExampleHelper.java

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,36 +32,60 @@
3232
* &#64;UpdateProvider(type=SqlProviderAdapter.class, method="update")
3333
* int update(UpdateStatementProvider updateStatement);
3434
*
35-
* default int updateByExampleSelective(SimpleTableRecord record, MyBatis3UpdateByExampleHelper helper) {
36-
* return helper.apply(UpdateDSL.updateWithMapper(this::update, simpleTable)
37-
* .set(id).equalToWhenPresent(record.getId())
38-
* .set(firstName).equalToWhenPresent(record::getFirstName)
39-
* .set(lastName).equalToWhenPresent(record::getLastName)
40-
* .set(birthDate).equalToWhenPresent(record::getBirthDate)
41-
* .set(employed).equalToWhenPresent(record::getEmployed)
42-
* .set(occupation).equalToWhenPresent(record::getOccupation))
43-
* .build()
44-
* .execute();
35+
* default MyBatis3UpdateByExampleCompleter updateByExampleSelective(MyBatis3UpdateByExampleHelper helper) {
36+
* return new MyBatis3UpdateByExampleCompleter.Builder&lt;SimpleTableRecord&gt;()
37+
* .withHelper(helper)
38+
* .withMapper(this::update)
39+
* .withTable(simpleTable)
40+
* .withValueSetter((record, dsl) -&gt;
41+
* dsl.set(id).equalToWhenPresent(record::getId)
42+
* .set(firstName).equalToWhenPresent(record::getFirstName)
43+
* .set(lastName).equalToWhenPresent(record::getLastName)
44+
* .set(birthDate).equalToWhenPresent(record::getBirthDate)
45+
* .set(employed).equalToWhenPresent(record::getEmployed)
46+
* .set(occupation).equalToWhenPresent(record::getOccupation))
47+
* .build();
4548
* }
4649
* </pre>
4750
*
4851
* <p>And then call the simplified default method like this:
4952
*
5053
* <pre>
51-
* int rows = mapper.updateByExampleSelective(record, q -&gt;
54+
* int rows = mapper.updateByExampleSelective(q -&gt;
5255
* q.where(id, isEqualTo(100))
53-
* .and(firstName, isEqualTo("Joe")));
56+
* .and(firstName, isEqualTo("Joe")))
57+
* .usingRecord(record);
5458
* </pre>
5559
*
56-
* <p>You can also do an "update all" with the following code:
60+
* <p>You can implement an "update all" with the following code:
5761
*
5862
* <pre>
59-
* int rows = mapper.updateByExampleSelective(record, q -&gt; q);
63+
* int rows = mapper.updateByExampleSelective(q -&gt; q)
64+
* .usingRecord(record);
6065
* </pre>
6166
*
67+
* <p>Or
68+
*
69+
* <pre>
70+
* int rows = mapper.updateByExampleSelective(MyBatis3UpdateByExampleHelper.allRows())
71+
* .usingRecord(record);
72+
* </pre>
73+
*
74+
* @see MyBatis3UpdateByExampleCompleter
75+
* @see MyBatis3UpdateByExampleValueSetter
76+
*
6277
* @author Jeff Butler
6378
*/
6479
@FunctionalInterface
6580
public interface MyBatis3UpdateByExampleHelper extends
6681
Function<UpdateDSL<MyBatis3UpdateModelAdapter<Integer>>, Buildable<MyBatis3UpdateModelAdapter<Integer>>> {
82+
83+
/**
84+
* Returns a helper that can be used to update every row in a table.
85+
*
86+
* @return the helper that will update every row in a table
87+
*/
88+
static MyBatis3UpdateByExampleHelper allRows() {
89+
return h -> h;
90+
}
6791
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright 2016-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.util.mybatis3;
17+
18+
import java.util.function.BiFunction;
19+
20+
import org.mybatis.dynamic.sql.update.MyBatis3UpdateModelAdapter;
21+
import org.mybatis.dynamic.sql.update.UpdateDSL;
22+
23+
/**
24+
* Represents a function that can be used to create an "UpdateByExample" method in the style
25+
* of MyBatis Generator. When using this function, you can create a method that will map record fields to
26+
* tables columns to be updated in a common mapper, and then allow a user to set a where clause as needed.
27+
*
28+
* @author Jeff Butler
29+
*
30+
* @see MyBatis3UpdateByExampleHelper
31+
*
32+
* @param <T> the type of record that will be updated
33+
*/
34+
@FunctionalInterface
35+
public interface MyBatis3UpdateByExampleValueSetter<T> extends
36+
BiFunction<T, UpdateDSL<MyBatis3UpdateModelAdapter<Integer>>, UpdateDSL<MyBatis3UpdateModelAdapter<Integer>>> {
37+
}

src/test/java/examples/simple/SimpleTableAnnotatedMapperNewStyle.java

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3CountByExampleHelper;
4545
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3DeleteByExampleHelper;
4646
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3SelectByExampleHelper;
47+
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3UpdateByExampleCompleter;
4748
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3UpdateByExampleHelper;
4849

4950
/**
@@ -170,30 +171,36 @@ default SimpleTableRecord selectByPrimaryKey(Integer id_) {
170171
.execute();
171172
}
172173

173-
default int updateByExample(SimpleTableRecord record, MyBatis3UpdateByExampleHelper helper) {
174-
return helper.apply(UpdateDSL.updateWithMapper(this::update, simpleTable)
175-
.set(id).equalTo(record.getId())
176-
.set(firstName).equalTo(record::getFirstName)
177-
.set(lastName).equalTo(record::getLastName)
178-
.set(birthDate).equalTo(record::getBirthDate)
179-
.set(employed).equalTo(record::getEmployed)
180-
.set(occupation).equalTo(record::getOccupation))
181-
.build()
182-
.execute();
174+
default MyBatis3UpdateByExampleCompleter<SimpleTableRecord> updateByExample(MyBatis3UpdateByExampleHelper helper) {
175+
return new MyBatis3UpdateByExampleCompleter.Builder<SimpleTableRecord>()
176+
.withHelper(helper)
177+
.withMapper(this::update)
178+
.withTable(simpleTable)
179+
.withValueSetter((record, dsl) ->
180+
dsl.set(id).equalTo(record::getId)
181+
.set(firstName).equalTo(record::getFirstName)
182+
.set(lastName).equalTo(record::getLastName)
183+
.set(birthDate).equalTo(record::getBirthDate)
184+
.set(employed).equalTo(record::getEmployed)
185+
.set(occupation).equalTo(record::getOccupation))
186+
.build();
183187
}
184-
185-
default int updateByExampleSelective(SimpleTableRecord record, MyBatis3UpdateByExampleHelper helper) {
186-
return helper.apply(UpdateDSL.updateWithMapper(this::update, simpleTable)
187-
.set(id).equalToWhenPresent(record.getId())
188-
.set(firstName).equalToWhenPresent(record::getFirstName)
189-
.set(lastName).equalToWhenPresent(record::getLastName)
190-
.set(birthDate).equalToWhenPresent(record::getBirthDate)
191-
.set(employed).equalToWhenPresent(record::getEmployed)
192-
.set(occupation).equalToWhenPresent(record::getOccupation))
193-
.build()
194-
.execute();
188+
189+
default MyBatis3UpdateByExampleCompleter<SimpleTableRecord> updateByExampleSelective(MyBatis3UpdateByExampleHelper helper) {
190+
return new MyBatis3UpdateByExampleCompleter.Builder<SimpleTableRecord>()
191+
.withHelper(helper)
192+
.withMapper(this::update)
193+
.withTable(simpleTable)
194+
.withValueSetter((record, dsl) ->
195+
dsl.set(id).equalToWhenPresent(record::getId)
196+
.set(firstName).equalToWhenPresent(record::getFirstName)
197+
.set(lastName).equalToWhenPresent(record::getLastName)
198+
.set(birthDate).equalToWhenPresent(record::getBirthDate)
199+
.set(employed).equalToWhenPresent(record::getEmployed)
200+
.set(occupation).equalToWhenPresent(record::getOccupation))
201+
.build();
195202
}
196-
203+
197204
default int updateByPrimaryKey(SimpleTableRecord record) {
198205
return UpdateDSL.updateWithMapper(this::update, simpleTable)
199206
.set(firstName).equalTo(record::getFirstName)

0 commit comments

Comments
 (0)