1 /*
2 * Copyright 2016-2025 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.mybatis.dynamic.sql.update;
17
18 import java.util.function.Function;
19 import java.util.function.ToIntFunction;
20
21 import org.mybatis.dynamic.sql.SqlTable;
22 import org.mybatis.dynamic.sql.util.Buildable;
23 import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils;
24
25 /**
26 * Represents a function that can be used to create a general update method. When using this function,
27 * you can create a method that does not require a user to call the build() and render() methods - making
28 * client code look a bit cleaner.
29 *
30 * <p>This function is intended to be used in conjunction in the utility method like
31 * {@link MyBatis3Utils#update(ToIntFunction, SqlTable, UpdateDSLCompleter)}
32 *
33 * <p>For example, you can create mapper interface methods like this:
34 *
35 * <pre>
36 * @UpdateProvider(type=SqlProviderAdapter.class, method="update")
37 * int update(UpdateStatementProvider updateStatement);
38 *
39 * default int update(UpdateDSLCompleter completer) {
40 return MyBatis3Utils.update(this::update, person, completer);
41 * }
42 * </pre>
43 *
44 * <p>And then call the simplified default method like this:
45 *
46 * <pre>
47 * int rows = mapper.update(c ->
48 * c.set(firstName).equalTo("Fred")
49 * .where(id, isEqualTo(100))
50 * );
51 * </pre>
52 *
53 * <p>You can implement an "update all" simply by omitting a where clause:
54 *
55 * <pre>
56 * int rows = mapper.update(c ->
57 * c.set(firstName).equalTo("Fred")
58 * );
59 * </pre>
60 *
61 * <p>You could also implement a helper method that would set fields based on values of a record. For example,
62 * the following method would set all fields of a row based on whether the values are null:
63 *
64 * <pre>
65 * static UpdateDSL<UpdateModel> updateSelectiveColumns(PersonRecord record,
66 * UpdateDSL<UpdateModel> dsl) {
67 * return dsl.set(id).equalToWhenPresent(record::getId)
68 * .set(firstName).equalToWhenPresent(record::getFirstName)
69 * .set(lastName).equalToWhenPresent(record::getLastName)
70 * .set(birthDate).equalToWhenPresent(record::getBirthDate)
71 * .set(employed).equalToWhenPresent(record::getEmployed)
72 * .set(occupation).equalToWhenPresent(record::getOccupation);
73 * }
74 * </pre>
75 *
76 * <p>The helper method could be used like this:
77 *
78 * <pre>
79 * rows = mapper.update(c ->
80 * PersonMapper.updateSelectiveColumns(record, c)
81 * .where(id, isLessThan(100)));
82 * </pre>
83 *
84 * <p>In this way, you could mimic the function of the old style "updateByExampleSelective" methods from
85 * MyBatis Generator.
86 *
87 * @author Jeff Butler
88 */
89 @FunctionalInterface
90 public interface UpdateDSLCompleter extends
91 Function<UpdateDSL<UpdateModel>, Buildable<UpdateModel>> {
92 }