Skip to content

Commit f051575

Browse files
committed
Documentation updates
1 parent f19209a commit f051575

File tree

4 files changed

+187
-60
lines changed

4 files changed

+187
-60
lines changed

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ One capability is that very expressive dynamic queries can be generated. Here's
5656
```java
5757
@Test
5858
public void testComplexCondition() {
59-
SqlSession sqlSession = sqlSessionFactory.openSession();
60-
try {
59+
try(SqlSession sqlSession = sqlSessionFactory.openSession()) {
6160
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
6261

6362
SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight)
@@ -72,8 +71,6 @@ One capability is that very expressive dynamic queries can be generated. Here's
7271

7372
List<AnimalData> animals = mapper.selectMany(selectStatement);
7473
assertThat(animals.size()).isEqualTo(4);
75-
} finally {
76-
sqlSession.close();
7774
}
7875
}
7976
```

src/site/markdown/docs/howItWorks.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,11 @@ public interface Mapper {
6161
Using this mapper with MyBatis looks like this:
6262

6363
```java
64-
SqlSession sqlSession = sqlSessionFactory.openSession();
65-
try {
64+
try(SqlSession sqlSession = sqlSessionFactory.openSession()) {
6665
Mapper mapper = sqlSession.getMapper(Mapper.class);
6766
Parameter parameter = new Parameter(2);
6867
TableCode tableCode = mapper.getTableCode(parameter);
6968
assertThat(tableCode.getId()).isEqualTo(2);
70-
} finally {
71-
sqlSession.close();
7269
}
7370
```
7471

src/site/markdown/docs/insert.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ A batch insert is a collection of statements that can be used to execute a JDBC
187187

188188
```java
189189
...
190-
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
191-
try {
190+
try(SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
192191
SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);
193192
List<SimpleTableRecord> records = getRecordsToInsert(); // not shown
194193

@@ -206,8 +205,6 @@ A batch insert is a collection of statements that can be used to execute a JDBC
206205
batchInsert.insertStatements().stream().forEach(mapper::insert);
207206

208207
session.commit();
209-
} finally {
210-
session.close();
211208
}
212209
...
213210
```

src/site/markdown/docs/mybatis3.md

Lines changed: 184 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,221 @@
11
# Specialized Support for MyBatis3
2-
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. But the library does have some additional specialized support for MyBatis3 beyond what is shown in the other examples.
2+
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, some of the techniques shown on this page may prove useful.
33

4-
This support is added to the DELETE, SELECT, and UPDATE statement generators and enables the creating of reusable "by example" methods as delivered in MyBatis Generator. These methods can provide some boilerplate code for the setup of the statement (a column list and table name for example), and allow the user to specify a where clause.
4+
This support is added to the DELETE, SELECT, and UPDATE statement generators and enables the creating of reusable methods as delivered in MyBatis Generator. These methods can provide some boilerplate code for the setup of the statement (a column list and table name for example), and allow the user to specify a where clause.
55

6-
With version 1.1.3, specialized interfaces were added that can further simplify client code.
6+
With version 1.1.3, specialized interfaces were added that can further simplify client code. This support enables the creation of methods that have similar functionality to some of the 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.
77

8-
## CountByExample Support
8+
## Count Method Support
99

10-
## DeleteByExample Support
10+
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.
1111

12-
## SelectByExample Support
12+
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 select:
1313

14-
Support for SelectByExample allows creating reusable methods where the user only need specify a where clause.
14+
```java
15+
@SelectProvider(type=SqlProviderAdapter.class, method="select")
16+
long count(SelectStatementProvider selectStatement);
17+
```
18+
19+
This is a standard method for MyBatis Dynamic SQL that executes a query and returns a `long`. The second method will reuse this method and supply everything needed to build the select statement except the where clause:
1520

1621
```java
17-
import static examples.simple.SimpleTableDynamicSqlSupport.*;
22+
default long count(MyBatis3CountHelper helper) {
23+
return helper.apply(SelectDSL.selectWithMapper(this::count, SqlBuilder.count())
24+
.from(simpleTable))
25+
.build()
26+
.execute();
27+
}
28+
```
1829

19-
import java.util.List;
30+
This method shows the use of `MyBatis3CountHelper` which is a specialization of a `java.util.Function` that will allow a user to supply a where clause. Clients can use the method as follows:
2031

21-
import org.apache.ibatis.annotations.Mapper;
22-
import org.apache.ibatis.annotations.Result;
23-
import org.apache.ibatis.annotations.Results;
24-
import org.apache.ibatis.annotations.SelectProvider;
25-
import org.apache.ibatis.type.JdbcType;
26-
import org.mybatis.dynamic.sql.select.SelectDSL;
27-
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
28-
import org.mybatis.dynamic.sql.util.SqlProviderAdapter;
29-
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3SelectByExampleHelper;
32+
```java
33+
long rows = mapper.count(h ->
34+
h.where(occupation, isNull()));
35+
```
3036

31-
@Mapper
32-
public interface SimpleTableMapper {
37+
There is a utility method that can be used to count all rows in a table:
38+
39+
```java
40+
long rows = mapper.count(MyBatis3CountHelper.allRows());
41+
```
42+
43+
## Delete Method Support
44+
45+
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.
46+
47+
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:
48+
49+
```java
50+
@DeleteProvider(type=SqlProviderAdapter.class, method="delete")
51+
int delete(DeleteStatementProvider deleteStatement);
52+
```
53+
54+
This is a standard method for MyBatis Dynamic SQL that executes a delete and returns an `int` - the number of rows deleted. The second method will reuse this method and supply everything needed to build the delete statement except the where clause:
55+
56+
```java
57+
default int delete(MyBatis3DeleteHelper helper) {
58+
return helper.apply(DeleteDSL.deleteFromWithMapper(this::delete, simpleTable))
59+
.build()
60+
.execute();
61+
}
62+
```
63+
64+
This method shows the use of `MyBatis3DeleteHelper` which is a specialization of a `java.util.Function` that will allow a user to supply a where clause. Clients can use the method as follows:
65+
66+
```java
67+
int rows = mapper.delete(h ->
68+
h.where(occupation, isNull()));
69+
```
70+
71+
There is a utility method that can be used to delete all rows in a table:
72+
73+
```java
74+
int rows = mapper.delete(MyBatis3DeleteHelper.allRows());
75+
```
76+
77+
## Select Method Support
78+
79+
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.
80+
81+
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:
82+
83+
```java
84+
@SelectProvider(type=SqlProviderAdapter.class, method="select")
85+
@Results(id="SimpleTableResult", value= {
86+
@Result(column="A_ID", property="id", jdbcType=JdbcType.INTEGER, id=true),
87+
@Result(column="first_name", property="firstName", jdbcType=JdbcType.VARCHAR),
88+
@Result(column="last_name", property="lastName", jdbcType=JdbcType.VARCHAR),
89+
@Result(column="birth_date", property="birthDate", jdbcType=JdbcType.DATE),
90+
@Result(column="employed", property="employed", jdbcType=JdbcType.VARCHAR),
91+
@Result(column="occupation", property="occupation", jdbcType=JdbcType.VARCHAR)
92+
})
93+
List<SimpleTableRecord> selectMany(SelectStatementProvider selectStatement);
3394

34-
@SelectProvider(type=SqlProviderAdapter.class, method="select")
35-
@Results(id="SimpleTableResult", value= {
36-
@Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
37-
@Result(column="first_name", property="firstName", jdbcType=JdbcType.VARCHAR),
38-
@Result(column="last_name", property="lastName", jdbcType=JdbcType.VARCHAR),
39-
@Result(column="birth_date", property="birthDate", jdbcType=JdbcType.DATE),
40-
@Result(column="employed", property="employed", jdbcType=JdbcType.VARCHAR),
41-
@Result(column="occupation", property="occupation", jdbcType=JdbcType.VARCHAR)
42-
})
43-
List<SimpleTableRecord> selectMany(SelectStatementProvider selectStatement);
95+
@SelectProvider(type=SqlProviderAdapter.class, method="select")
96+
@ResultMap("SimpleTableResult")
97+
Optional<SimpleTableRecord> selectOne(SelectStatementProvider selectStatement);
98+
```
99+
100+
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.
101+
102+
The `selectOne` method can be used to implement a `selectByPrimaryKey` method:
103+
104+
```java
105+
default Optional<SimpleTableRecord> selectByPrimaryKey(Integer id_) {
106+
return SelectDSL.selectWithMapper(this::selectOne, id.as("A_ID"), firstName, lastName, birthDate,
107+
employed, occupation)
108+
.from(simpleTable)
109+
.where(id, isEqualTo(id_))
110+
.build()
111+
.execute();
112+
}
113+
```
114+
115+
The `selectMany` 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:
116+
117+
```java
118+
default List<SimpleTableRecord> select(MyBatis3SelectHelper<SimpleTableRecord> helper) {
119+
return helper.apply(SelectDSL.selectWithMapper(this::selectMany, id.as("A_ID"), firstName, lastName, birthDate,
120+
employed, occupation)
121+
.from(simpleTable))
122+
.build()
123+
.execute();
124+
}
44125

45-
default List<SimpleTableRecord> selectByExample(MyBatis3SelectByExampleHelper<SimpleTableRecord> helper) {
46-
return helper.apply(SelectDSL.selectWithMapper(this::selectMany, id, firstName, lastName, birthDate, employed, occupation)
47-
.from(simpleTable))
48-
.build()
49-
.execute();
50-
}
126+
default List<SimpleTableRecord> selectDistinct(MyBatis3SelectHelper<SimpleTableRecord> helper) {
127+
return helper.apply(SelectDSL.selectDistinctWithMapper(this::selectMany, id.as("A_ID"), firstName, lastName,
128+
birthDate, employed, occupation)
129+
.from(simpleTable))
130+
.build()
131+
.execute();
51132
}
52133
```
53134

54-
Notice the `selectByExample` method - it specifies the column list and table name and accepts a lambda expression that can be used to build the WHERE clause. It also reuses the `selectMany` mapper method.
55135

56-
The code is used like this:
136+
These methods show the use of `MyBatis3SelectHelper` which is a specialization of a `java.util.Function` that will allow a user to supply a where clause and/or an order by clause.
137+
138+
Clients can use the methods as follows:
57139

58140
```java
59-
List<SimpleTableRecord> rows = mapper.selectByExample(q ->
60-
q.where(id, isEqualTo(1))
61-
.or(occupation, isNull()));
141+
List<SimpleTableRecord> rows = mapper.select(h ->
142+
h.where(id, isEqualTo(1))
143+
.or(occupation, isNull()));
62144
```
63145

64-
The following query will select all rows:
146+
There are utility methods that will select all rows in a table:
65147

66148
```java
67-
List<SimpleTableRecord> rows =
68-
mapper.selectByExample(MyBatis3SelectByExampleHelper.allRows());
149+
List<SimpleTableRecord> rows =
150+
mapper.selectByExample(MyBatis3SelectHelper.allRows());
69151
```
70152

71153
The following query will select all rows in a specified order:
72154

73155
```java
74-
List<SimpleTableRecord> rows =
75-
mapper.selectByExample(MyBatis3SelectByExampleHelper.allRowsOrderedBy(lastName, firstName));
156+
List<SimpleTableRecord> rows =
157+
mapper.selectByExample(MyBatis3SelectHelper.allRowsOrderedBy(lastName, firstName));
76158
```
77159

160+
## Update Method Support
161+
162+
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.
78163

79-
It is expected that MyBatis Generator will generate code that looks like this.
164+
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:
80165

166+
```java
167+
@UpdateProvider(type=SqlProviderAdapter.class, method="update")
168+
int update(UpdateStatementProvider updateStatement);
169+
```
170+
171+
This is a standard method for MyBatis Dynamic SQL that executes a query and returns an `int` - the number of rows updated. The second method will reuse this method and supply everything needed to build the update statement except the values and the where clause:
172+
173+
```java
174+
default int update(MyBatis3UpdateHelper helper) {
175+
return helper.apply(UpdateDSL.updateWithMapper(this::update, simpleTable))
176+
.build()
177+
.execute();
178+
}
179+
```
180+
181+
This method shows the use of `MyBatis3UpdateHelper` which is a specialization of a `java.util.Function` that will allow a user to supply values and a where clause. Clients can use the method as follows:
182+
183+
```java
184+
int rows = mapper.update(h ->
185+
h.set(occupation).equalTo("Programmer")
186+
.where(id, isEqualTo(100)));
187+
```
188+
189+
All rows in a table can be updated by simply omitting the where clause:
190+
191+
```java
192+
int rows = mapper.update(h ->
193+
h.set(occupation).equalTo("Programmer"));
194+
```
195+
196+
It is also possible to write a utility method that will set values. For example:
197+
198+
```java
199+
static UpdateDSL<MyBatis3UpdateModelAdapter<Integer>> setSelective(SimpleTableRecord record,
200+
UpdateDSL<MyBatis3UpdateModelAdapter<Integer>> dsl) {
201+
return dsl.set(id).equalToWhenPresent(record::getId)
202+
.set(firstName).equalToWhenPresent(record::getFirstName)
203+
.set(lastName).equalToWhenPresent(record::getLastName)
204+
.set(birthDate).equalToWhenPresent(record::getBirthDate)
205+
.set(employed).equalToWhenPresent(record::getEmployed)
206+
.set(occupation).equalToWhenPresent(record::getOccupation);
207+
}
208+
```
209+
210+
This method will selectively set values if corresponding fields in a record are non null. This method can be used as follows:
211+
212+
```java
213+
rows = mapper.update(h ->
214+
setSelective(updateRecord, h)
215+
.where(id, isEqualTo(100)));
216+
```
81217

82-
## Prior Support
218+
# Prior Support
83219
Prior to version 1.1.3, it was also possible to write reusable methods, but they were a bit inconsistent with other helper methods.
84220

85221
For example, it is possible to write a mapper interface like this:

0 commit comments

Comments
 (0)