-
Notifications
You must be signed in to change notification settings - Fork 212
/
Copy pathmybatis3.html
503 lines (450 loc) · 27.2 KB
/
mybatis3.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
<!DOCTYPE html>
<!--
| Generated by Apache Maven Doxia Site Renderer 2.0.0-M18 from src/site/markdown/docs/mybatis3.md at 03 Jun 2024
| Rendered using Apache Maven Fluido Skin 2.0.0-M9
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="generator" content="Apache Maven Doxia Site Renderer 2.0.0-M18" />
<title>MyBatis Dynamic SQL</title>
<link rel="stylesheet" href="../css/apache-maven-fluido-2.0.0-M9.min.css" />
<link rel="stylesheet" href="../css/site.css" />
<link rel="stylesheet" href="../css/print.css" media="print" />
<script src="../js/apache-maven-fluido-2.0.0-M9.min.js"></script>
</head>
<body>
<div class="container-fluid container-fluid-top">
<header>
<div id="banner">
<div class="pull-left"><div id="bannerLeft"><h1><a href="../docs/introduction.html">MyBatis Dynamic SQL</a></h1></div></div>
<div class="pull-right"><div id="bannerRight"><h1><a href="http://www.mybatis.org/" class="externalLink"><img class="imageLink" src="https://mybatis.org/images/mybatis-logo.png" alt="MyBatis logo" /> MyBatis</a></h1></div></div>
<div class="clear"><hr/></div>
</div>
<div id="breadcrumbs">
<ul class="breadcrumb">
<li id="publishDate">Last Published: 03 Jun 2024<span class="divider">|</span>
</li>
<li id="projectVersion">Version: 1.5.2</li>
</ul>
</div>
</header>
<div class="row-fluid">
<header id="leftColumn" class="span2">
<nav class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">User's Guide</li>
<li><a href="../docs/introduction.html">Introduction</a></li>
<li><a href="../docs/CHANGELOG.html">Change Log</a></li>
<li><a href="../docs/quickStart.html">Quick Start</a></li>
<li><a href="../docs/exceptions.html">Exceptions thrown by the Library</a></li>
<li><a href="../docs/configuration.html">Configuration of the Library</a></li>
<li><a href="../docs/databaseObjects.html">Modeling Database Objects</a></li>
<li><a href="../docs/whereClauses.html"><span class="icon-chevron-down"></span>WHERE Clause Support</a>
<ul class="nav nav-list">
<li><a href="../docs/conditions.html">WHERE Conditions</a></li>
</ul></li>
<li><a href="../docs/select.html"><span class="icon-chevron-down"></span>SELECT Statements</a>
<ul class="nav nav-list">
<li><a href="../docs/caseExpressions.html">Case Expressions</a></li>
<li><a href="../docs/complexQueries.html">Complex Queries</a></li>
</ul></li>
<li><a href="../docs/delete.html">DELETE Statements</a></li>
<li><a href="../docs/insert.html">INSERT Statements</a></li>
<li><a href="../docs/update.html">UPDATE Statements</a></li>
<li><a href="../docs/subQueries.html">SubQuery Support</a></li>
<li><a href="../docs/functions.html">Database Functions</a></li>
<li class="active"><a>MyBatis3 Support</a></li>
<li><a href="../docs/spring.html">Spring Support</a></li>
<li><a href="../docs/springBatch.html">Spring Batch Support</a></li>
<li><a href="../docs/kotlinOverview.html"><span class="icon-chevron-right"></span>Kotlin Support</a></li>
<li><a href="../docs/howItWorks.html">How it Works</a></li>
<li><a href="../docs/extending.html">Extending the Library</a></li>
<li><a href="../docs/codingStandards.html">Coding Standards</a></li>
<li><a href="../docs/motivation.html">Motivation</a></li>
<li class="nav-header">Project Documentation</li>
<li><a href="../project-info.html"><span class="icon-chevron-right"></span>Project Information</a></li>
<li><a href="../project-reports.html"><span class="icon-chevron-right"></span>Project Reports</a></li>
</ul>
</nav>
<div class="well sidebar-nav">
<div id="poweredBy">
<div class="clear"></div>
<div class="clear"></div>
<a href="https://maven.apache.org/" class="builtBy" target="_blank"><img class="builtBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /></a>
</div>
</div>
</header>
<main id="bodyColumn" class="span10">
<section><a id="Specialized_Support_for_MyBatis3"></a>
<h1>Specialized Support for MyBatis3</h1>
<p>Most of the examples shown on this site are for usage with MyBatis3 - even though the library does support other SQL
runtimes like Spring JDBC templates. In addition to the examples shown elsewhere, the library has additional specialized
support for MyBatis3 beyond what is shown in the other examples. This support mainly exists to support MyBatis Generator
and the code generated by that tool. Even without MyBatis Generator, the techniques shown on this page may prove useful.</p>
<p>The goal of this support is to reduce the amount of boilerplate code needed for a typical CRUD mapper. For example, this
support allows you to create a reusable SELECT method where the user only needs to specify a WHERE clause.</p>
<p>With version 1.1.3, specialized interfaces and utilities were added that can further simplify client code. This support
enables the creation of methods that have similar functionality to methods generated in previous versions of MyBatis
generator like countByExample, deleteByExample, and selectByExample. We no longer use the “by example” terms for these
methods as this library has eliminated the Example class that was generated by prior versions of MyBatis Generator.</p><section><a id="Common_Mapper_Support"></a>
<h2>Common Mapper Support</h2>
<p>The library includes several common mappers for MyBatis that can be injected into a MyBatis configuration as-is, or can be
extended. These mappers can be used to eliminate repetitive boilerplate code for several operations - namely count queries,
deletes, inserts, and updates. In addition, there is a common select mapper that can be used to avoid writing custom
result maps for every query. The common select mapper provides a row mapper function that is very similar to Spring
JDBC template.</p><section><a id="Common_Count.2C_Delete.2C_Insert.2C_and_Update_Mappers"></a>
<h3>Common Count, Delete, Insert, and Update Mappers</h3>
<p>These mappers provide utility functions that execute simple queries. They can be used as-as, or can be extended. They
provide methods as follows:</p>
<table class="table table-striped">
<thead>
<tr class="a">
<th>Mapper</th>
<th>Methods(s)</th></tr></thead><tbody>
<tr class="b">
<td><code>org.mybatis.dynamic.sql.util.mybatis3.CommonCountMapper</code></td>
<td><code>long count(SelectStatementProvider)</code></td></tr>
<tr class="a">
<td><code>org.mybatis.dynamic.sql.util.mybatis3.CommonDeleteMapper</code></td>
<td><code>int delete(DeleteStatementProvider)</code></td></tr>
<tr class="b">
<td><code>org.mybatis.dynamic.sql.util.mybatis3.CommonInsertMapper<T></code><br />(extends <code>CommonGeneralInsertMapper</code>)</td>
<td><code>int insert(InsertStatementProvider<T>)</code><br /><code>int insertMultiple(MultiRowInsertStatementProvider<T>)</code></td></tr>
<tr class="a">
<td><code>org.mybatis.dynamic.sql.util.mybatis3.CommonGeneralInsertMapper</code></td>
<td><code>int generalInsert(GeneralInsertStatementProvider)</code><br /><code>int insertSelect(InsertSelectStatementProvider)</code></td></tr>
<tr class="b">
<td><code>org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper</code></td>
<td><code>int update(UpdateStatementProvider)</code></td></tr></tbody>
</table>
<p>These mappers, as well as the <code>CommonSelectMapper</code>, can be used to create a general purpose CRUD mapper as follows:</p>
<pre><code class="language-java">import org.apache.ibatis.annotations.Mapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonCountMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonDeleteMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonInsertMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper;
import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper;
@Mapper
public interface FooMapper extends CommonCountMapper, CommonDeleteMapper, CommonInsertMapper<Foo>, CommonSelectMapper,
CommonUpdateMapper {
}
</code></pre>
<p>This mapper can be extended with default methods as shown below.</p></section><section><a id="Common_Select_Mapper"></a>
<h3>Common Select Mapper</h3>
<p>MyBatis is very good at mapping result sets to objects - this is one of its primary differentiators. MyBatis also requires
that you predefine the mappings for every possibility. This presents a challenge if you want very dynamic column lists
in a query. This library provides a generalized MyBatis mapper that can assist with that problem.</p>
<p>The general mapper is <code>org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper</code>. This mapper can be injected into a
MyBatis configuration as is, or it can be extended by an existing mapper.</p>
<p>The mapper contains three types of methods:</p>
<ol style="list-style-type: decimal;">
<li>The <code>selectOneMappedRow</code> and <code>selectManyMappedRows</code> methods allow you to use select statements with
any number of columns. MyBatis will process the rows and return a Map of values, or a List of Maps for multiple rows.</li>
<li>The <code>selectOne</code> and <code>selectMany</code> methods also allow you to use select statements with any number of columns. These methods
also allow you to specify a function that will transform a Map of row values into a specific object.</li>
<li>The other methods are for result sets with a single column. There are functions for many
data types (Integer, Long, String, etc.) There are also functions that return a single value, and Optional value,
or a List of values.</li>
</ol>
<p>An example of using the mapped row methods follows:</p>
<pre><code class="language-java">package foo.service;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import java.util.List;
import java.util.Map;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper;
public class MyService {
public List<Map<String,Object>> generalSearch() {
CommonSelectMapper mapper = getGeneralMapper(); // not shown
SelectStatementProvider selectStatement = select(id, description)
.from(foo)
.where(description. isLike("%bar%"))
.build()
.render(RenderingStrategies.MYBATIS3);
return mapper.selectManyMappedRows(selectStatement);
}
}
</code></pre>
<p>As you can see, the method returns a List of Maps containing the row values. The Map key will be the column name as
returned from the database (typically in upper case), and the column value as returned from the <code>ResultSet.getObject()</code>.
See your JDBC driver's documentation for details about how SQL types are mapped to Java types to determine the data type
for your specific database.</p>
<p>This method works well, but usually it is better to marshal the result set into actual objects. This can be accomplished
as follows:</p>
<pre><code class="language-java">package foo.service;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import java.util.List;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper;
public class MyService {
public List<TableCode> generalSearch() {
CommonSelectMapper mapper = getGeneralMapper(); // not shown
SelectStatementProvider selectStatement = select(id, description)
.from(foo)
.where(description. isLike("%bar%"))
.build()
.render(RenderingStrategies.MYBATIS3);
return mapper.selectMany(selectStatement, m -> {
TableCode tc = new TableCode();
tc.setId((Integer) m.get("ID"));
tc.setDescription((String) m.get("DESCRIPTION"));
return tc;
});
}
}
</code></pre>
<p>With this method you can centralize all the database specific operations in a single method.</p>
<p>If you only have a single column in the result set, the general mapper provides methods to retrieve the value directly.
For example:</p>
<pre><code class="language-java">package foo.service;
import static org.mybatis.dynamic.sql.SqlBuilder.*;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper;
public class MyService {
public Long getAverageAge() {
CommonSelectMapper mapper = getGeneralMapper(); // not shown
SelectStatementProvider selectStatement = select(avg(age))
.from(foo)
.where(description. isLike("%bar%"))
.build()
.render(RenderingStrategies.MYBATIS3);
return mapper.selectOneLong(selectStatement);
}
}
</code></pre></section></section><section><a id="Count_Method_Support"></a>
<h2>Count Method Support</h2>
<p>The goal of count method support is to enable the creation of methods that execute a count query allowing a user to
specify a where clause at runtime, but abstracting away all other details.</p>
<p>To use this support, we envision creating several methods on a MyBatis mapper interface. The first method is the
standard MyBatis Dynamic SQL method that will execute a select:</p>
<pre><code class="language-java">@SelectProvider(type=SqlProviderAdapter.class, method="select")
long count(SelectStatementProvider selectStatement);
</code></pre>
<p>This is a standard method for MyBatis Dynamic SQL that executes a query and returns a <code>long</code>. The other methods will reuse
this method and supply everything needed to build the select statement except the where clause. In lieu of writing this method,
you could extend <code>org.mybatis.dynamic.sql.util.mybatis3.CommonCountMapper</code> instead. There are several variants
of count queries that may be useful:</p>
<ol style="list-style-type: decimal;">
<li><code>count(*)</code> - counts the number of rows that match a where clause</li>
<li><code>count(column)</code> - counts the number of non-null column values that match a where clause</li>
<li><code>count(distinct column)</code> - counts the number of unique column values that match a where clause</li>
</ol>
<p>Corresponding mapper methods are as follows:</p>
<pre><code class="language-java">default long count(CountDSLCompleter completer) { // count(*)
return MyBatis3Utils.countFrom(this::count, person, completer);
}
default long count(BasicColumn column, CountDSLCompleter completer) { // count(column)
return MyBatis3Utils.count(this::count, column, person, completer);
}
default long countDistinct(BasicColumn column, CountDSLCompleter completer) { // count(distinct column)
return MyBatis3Utils.countDistinct(this::count, column, person, completer);
}
</code></pre>
<p>These methods show the use of <code>CountDSLCompleter</code> which is a specialization of a <code>java.util.Function</code> that will allow
a user to supply a where clause. Clients can use the method as follows:</p>
<pre><code class="language-java">long rows = mapper.count(c ->
c.where(occupation, isNull()));
</code></pre>
<p>There is a utility method that can be used to count all rows in a table:</p>
<pre><code class="language-java">long rows = mapper.count(CountDSLCompleter.allRows());
</code></pre></section><section><a id="Delete_Method_Support"></a>
<h2>Delete Method Support</h2>
<p>The goal of delete method support is to enable the creation of methods that execute a delete statement allowing a user
to specify a where clause at runtime, but abstracting away all other details.</p>
<p>To use this support, we envision creating two methods on a MyBatis mapper interface. The first method is the standard
MyBatis Dynamic SQL method that will execute a delete:</p>
<pre><code class="language-java">@DeleteProvider(type=SqlProviderAdapter.class, method="delete")
int delete(DeleteStatementProvider deleteStatement);
</code></pre>
<p>This is a standard method for MyBatis Dynamic SQL that executes a delete and returns an <code>int</code> - the number of rows deleted.
In lieu of writing this method, you could extend <code>org.mybatis.dynamic.sql.util.mybatis3.CommonDeleteMapper</code> instead.
The second method will reuse this method and supply everything needed to build the delete statement except the where clause:</p>
<pre><code class="language-java">default int delete(DeleteDSLCompleter completer) {
return MyBatis3Utils.deleteFrom(this::delete, person, completer);
}
</code></pre>
<p>This method shows the use of <code>DeleteDSLCompleter</code> which is a specialization of a <code>java.util.Function</code> that will allow a
user to supply a where clause. Clients can use the method as follows:</p>
<pre><code class="language-java">int rows = mapper.delete(c ->
c.where(occupation, isNull()));
</code></pre>
<p>There is a utility method that can be used to delete all rows in a table:</p>
<pre><code class="language-java">int rows = mapper.delete(DeleteDSLCompleter.allRows());
</code></pre></section><section><a id="Insert_Method_Support"></a>
<h2>Insert Method Support</h2>
<p>The goal of insert method support is to remove some of the boilerplate code from insert methods in a mapper interfaces.</p>
<p>To use this support, we envision creating several methods on a MyBatis mapper interface. The first methods are the
standard MyBatis methods that will execute an insert:</p>
<pre><code class="language-java">@InsertProvider(type=SqlProviderAdapter.class, method="insert")
int insert(InsertStatementProvider<PersonRecord> insertStatement);
@InsertProvider(type=SqlProviderAdapter.class, method="generalInsert")
int generalInsert(GeneralInsertStatementProvider insertStatement);
@InsertProvider(type=SqlProviderAdapter.class, method="insertMultiple")
int insertMultiple(MultiRowInsertStatementProvider<PersonRecord> insertStatement);
</code></pre>
<p>These methods are standard methods for MyBatis Dynamic SQL. They execute a single row insert, a general insert, and a
multiple row insert. In lieu of writing these methods, you could extend
<code>org.mybatis.dynamic.sql.util.mybatis3.CommonInsertMapper</code> instead.</p>
<p>These methods can be used to implement simplified insert methods:</p>
<pre><code class="language-java">default int insert(UnaryOperator<GeneralInsertDSL> completer) {
return MyBatis3Utils.insert(this::generalInsert, person, completer);
}
default int insert(PersonRecord record) {
return MyBatis3Utils.insert(this::insert, record, 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")
);
}
default int insertMultiple(PersonRecord...records) {
return insertMultiple(Arrays.asList(records));
}
default int insertMultiple(Collection<PersonRecord> 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")
);
}
</code></pre>
<p>The first insert method is a general insert and can be used to create arbitrary inserts with different combinations of
columns specified. The other methods have the insert statements mapped to a POJO “record” class that holds values for
the insert statement.</p></section><section><a id="Select_Method_Support"></a>
<h2>Select Method Support</h2>
<p>The goal of select method support is to enable the creation of methods that execute a select statement allowing a user
to specify a where clause and/or order by clause at runtime, but abstracting away all other details.</p>
<p>To use this support, we envision creating several methods on a MyBatis mapper interface. The first two methods are the
standard MyBatis Dynamic SQL method that will execute a select:</p>
<pre><code class="language-java">@SelectProvider(type=SqlProviderAdapter.class, method="select")
@Results(id="PersonResult", value= {
@Result(column="A_ID", property="id", jdbcType=JdbcType.INTEGER, id=true),
@Result(column="first_name", property="firstName", jdbcType=JdbcType.VARCHAR),
@Result(column="last_name", property="lastName", jdbcType=JdbcType.VARCHAR),
@Result(column="birth_date", property="birthDate", jdbcType=JdbcType.DATE),
@Result(column="employed", property="employed", jdbcType=JdbcType.VARCHAR),
@Result(column="occupation", property="occupation", jdbcType=JdbcType.VARCHAR)
})
List<PersonRecord> selectMany(SelectStatementProvider selectStatement);
@SelectProvider(type=SqlProviderAdapter.class, method="select")
@ResultMap("PersonResult")
Optional<PersonRecord> selectOne(SelectStatementProvider selectStatement);
</code></pre>
<p>These two methods are standard methods for MyBatis Dynamic SQL. They execute a select and return either a list of
records, or a single record.</p>
<p>We also envision creating a static field for a reusable list of columns for a select statement:</p>
<pre><code class="language-java">BasicColumn[] selectList =
BasicColumn.columnList(id.as("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId);
</code></pre>
<p>The <code>selectOne</code> method can be used to implement a generalized select one method:</p>
<pre><code class="language-java">default Optional<PersonRecord> selectOne(SelectDSLCompleter completer) {
return MyBatis3Utils.selectOne(this::selectOne, selectList, person, completer);
}
</code></pre>
<p>This method shows the use of <code>SelectDSLCompleter</code> which is a specialization of a <code>java.util.Function</code> that will allow a
user to supply a where clause.</p>
<p>The general <code>selectOne</code> method can be used to implement a <code>selectByPrimaryKey</code> method:</p>
<pre><code class="language-java">default Optional<PersonRecord> selectByPrimaryKey(Integer id_) {
return selectOne(c ->
c.where(id, isEqualTo(id_))
);
}
</code></pre>
<p>The <code>selectMany</code> method can be used to implement generalized select methods where a user can specify a where clause
and/or an order by clause. Typically, we recommend two of these methods - for select, and select distinct:</p>
<pre><code class="language-java">default List<PersonRecord> select(SelectDSLCompleter completer) {
return MyBatis3Utils.selectList(this::selectMany, selectList, person, completer);
}
default List<PersonRecord> selectDistinct(SelectDSLCompleter completer) {
return MyBatis3Utils.selectDistinct(this::selectMany, selectList, person, completer);
}
</code></pre>
<p>These methods show the use of <code>SelectDSLCompleter</code> which is a specialization of a <code>java.util.Function</code> that will
allow a user to supply a where clause and/or an order by clause.</p>
<p>Clients can use the methods as follows:</p>
<pre><code class="language-java">List<PersonRecord> rows = mapper.select(c ->
c.where(id, isEqualTo(1))
.or(occupation, isNull()));
</code></pre>
<p>There are utility methods that will select all rows in a table:</p>
<pre><code class="language-java">List<PersonRecord> rows =
mapper.select(SelectDSLCompleter.allRows());
</code></pre>
<p>The following query will select all rows in a specified order:</p>
<pre><code class="language-java">List<PersonRecord> rows =
mapper.select(SelectDSLCompleter.allRowsOrderedBy(lastName, firstName));
</code></pre></section><section><a id="Update_Method_Support"></a>
<h2>Update Method Support</h2>
<p>The goal of update method support is to enable the creation of methods that execute an update statement allowing a user
to specify values to set and a where clause at runtime, but abstracting away all other details.</p>
<p>To use this support, we envision creating several methods on a MyBatis mapper interface. The first method is a standard
MyBatis Dynamic SQL method that will execute a update:</p>
<pre><code class="language-java">@UpdateProvider(type=SqlProviderAdapter.class, method="update")
int update(UpdateStatementProvider updateStatement);
</code></pre>
<p>This is a standard method for MyBatis Dynamic SQL that executes a query and returns an <code>int</code> - the number of rows updated.
In lieu of writing this method, you could extend <code>org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper</code> instead.
The second method will reuse this method and supply everything needed to build the update statement except the values
and the where clause:</p>
<pre><code class="language-java">default int update(UpdateDSLCompleter completer) {
return MyBatis3Utils.update(this::update, person, completer);
}
</code></pre>
<p>This method shows the use of <code>UpdateDSLCompleter</code> which is a specialization of a <code>java.util.Function</code> that will allow a
user to supply values and a where clause. Clients can use the method as follows:</p>
<pre><code class="language-java">int rows = mapper.update(c ->
c.set(occupation).equalTo("Programmer")
.where(id, isEqualTo(100)));
</code></pre>
<p>All rows in a table can be updated by simply omitting the where clause:</p>
<pre><code class="language-java">int rows = mapper.update(c ->
c.set(occupation).equalTo("Programmer"));
</code></pre>
<p>It is also possible to write a utility method that will set values. For example:</p>
<pre><code class="language-java">static UpdateDSL<UpdateModel> updateSelectiveColumns(PersonRecord row,
UpdateDSL<UpdateModel> dsl) {
return dsl.set(id).equalToWhenPresent(row::getId)
.set(firstName).equalToWhenPresent(row::getFirstName)
.set(lastName).equalToWhenPresent(row::getLastName)
.set(birthDate).equalToWhenPresent(row::getBirthDate)
.set(employed).equalToWhenPresent(row::getEmployed)
.set(occupation).equalToWhenPresent(row::getOccupation);
}
</code></pre>
<p>This method will selectively set values if corresponding fields in a record are non null. This method can be used as follows:</p>
<pre><code class="language-java">rows = mapper.update(h ->
updateSelectiveColumns(updateRecord, h)
.where(id, isEqualTo(100)));
</code></pre></section></section>
</main>
</div>
</div>
<hr/>
<footer>
<div class="container-fluid">
<div class="row-fluid">
<p>© 2016–2024
<a href="https://www.mybatis.org/">MyBatis.org</a>
</p>
</div>
</div>
</footer>
<script>
if(anchors) {
anchors.add();
}
</script>
</body>
</html>