Skip to content

Commit 04890dc

Browse files
committed
Create a reusable general mapper for MyBatis
1 parent bc09e87 commit 04890dc

File tree

12 files changed

+941
-186
lines changed

12 files changed

+941
-186
lines changed

pom.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@
208208
<version>5.2.8.RELEASE</version>
209209
<scope>provided</scope>
210210
</dependency>
211+
<dependency>
212+
<groupId>org.mybatis</groupId>
213+
<artifactId>mybatis</artifactId>
214+
<version>3.5.5</version>
215+
<scope>provided</scope>
216+
</dependency>
211217

212218
<dependency>
213219
<groupId>org.junit.jupiter</groupId>
@@ -233,12 +239,6 @@
233239
<version>3.17.2</version>
234240
<scope>test</scope>
235241
</dependency>
236-
<dependency>
237-
<groupId>org.mybatis</groupId>
238-
<artifactId>mybatis</artifactId>
239-
<version>3.5.5</version>
240-
<scope>test</scope>
241-
</dependency>
242242
<dependency>
243243
<groupId>org.mybatis</groupId>
244244
<artifactId>mybatis-spring</artifactId>
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
/*
2+
* Copyright 2016-2020 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.math.BigDecimal;
19+
import java.util.List;
20+
import java.util.Map;
21+
import java.util.Optional;
22+
import java.util.function.Function;
23+
import java.util.stream.Collectors;
24+
25+
import org.apache.ibatis.annotations.SelectProvider;
26+
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
27+
import org.mybatis.dynamic.sql.util.SqlProviderAdapter;
28+
29+
/**
30+
* This is a general purpose MyBatis mapper. It allows you to execute select statements without having to
31+
* write a custom {@link org.apache.ibatis.annotations.ResultMap} for each statement.
32+
*
33+
* <p>This mapper contains two types of methods:
34+
* <ul>
35+
* <li>selectOneMappedRow, selectOne, selectManyMappedRows, and selectMany can be used to process result sets with
36+
* any number of columns. The row values are processed by MyBatis and returned in a Map. A function can
37+
* be applied to the Map to create custom objects if desired</li>
38+
* <li>The other methods are for result sets with a single column. There are functions for many different
39+
* data types (Integer, Long, String, etc.) and functions that return a single value, and Optional value,
40+
* or a List of values</li>
41+
* </ul>
42+
*
43+
* <p>This mapper can be injected as-is into a MyBatis configuration, or it can be extended with existing mappers.</p>
44+
*
45+
* @author Jeff Butler
46+
*/
47+
public interface GeneralMapper {
48+
/**
49+
* Select a single row as a Map of values. The row may have any number of columns.
50+
* The Map key will be the column name as returned from the
51+
* database (may be aliased if an alias is specified in the select statement). Map entries will be
52+
* of data types determined by the JDBC driver. MyBatis will call ResultSet.getObject() to retrieve
53+
* values from the ResultSet. Reference your JDBC driver documentation to learn about type mappings
54+
* for your specific database.
55+
*
56+
* @param selectStatement the select statement
57+
* @return A Map containing the row values.
58+
*/
59+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
60+
Map<String, Object> selectOneMappedRow(SelectStatementProvider selectStatement);
61+
62+
/**
63+
* Select a single row of values and then convert the values to a custom type. This is similar
64+
* to the Spring JDBC template method of processing result sets. In this case, MyBatis will first extract
65+
* the row values into a Map, and then a row mapper can retrieve values from the Map and use them
66+
* to construct a custom object.
67+
*
68+
* <p>See {@link GeneralMapper#selectOneMappedRow(SelectStatementProvider)} for details about
69+
* how MyBatis will construct the Map of values.
70+
*
71+
* @param selectStatement the select statement
72+
* @param rowMapper a function that will convert a Map of row values to the desired data type
73+
* @param <R> the datatype of the converted object
74+
* @return the converted object
75+
*/
76+
default <R> R selectOne(SelectStatementProvider selectStatement,
77+
Function<Map<String, Object>, R> rowMapper) {
78+
return rowMapper.apply(selectOneMappedRow(selectStatement));
79+
}
80+
81+
/**
82+
* Select any number of rows and return a List of Maps containing row values (one Map for each row returned).
83+
* The rows may have any number of columns.
84+
* The Map key will be the column name as returned from the
85+
* database (may be aliased if an alias is specified in the select statement). Map entries will be
86+
* of data types determined by the JDBC driver. MyBatis will call ResultSet.getObject() to retrieve
87+
* values from the ResultSet. Reference your JDBC driver documentation to learn about type mappings
88+
* for your specific database.
89+
*
90+
* @param selectStatement the select statement
91+
* @return A List of Maps containing the row values.
92+
*/
93+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
94+
List<Map<String, Object>> selectManyMappedRows(SelectStatementProvider selectStatement);
95+
96+
/**
97+
* Select any number of rows and then convert the values to a custom type. This is similar to the
98+
* Spring JDBC template method of processing result sets. In this case, MyBatis will first extract the
99+
* row values into a List of Map, and them a row mapper can retrieve values from the Map and use them
100+
* to construct a custom object for each row.
101+
*
102+
* @param selectStatement the select statement
103+
* @param rowMapper a function that will convert a Map of row values to the desired data type
104+
* @param <R> the datatype of the converted object
105+
* @return the List of converted objects
106+
*/
107+
default <R> List<R> selectMany(SelectStatementProvider selectStatement,
108+
Function<Map<String, Object>, R> rowMapper) {
109+
return selectManyMappedRows(selectStatement).stream()
110+
.map(rowMapper)
111+
.collect(Collectors.toList());
112+
}
113+
114+
/**
115+
* Retrieve a single {@link java.math.BigDecimal} from a result set. The result set must have
116+
* only one column and one or zero rows. The column must be retrievable from the result set
117+
* via the ResultSet.getBigDecimal() method.
118+
*
119+
* @param selectStatement the select statement
120+
* @return the extracted value. May be null if zero rows are returned, or if the returned
121+
* column is null
122+
*/
123+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
124+
BigDecimal selectOneBigDecimal(SelectStatementProvider selectStatement);
125+
126+
/**
127+
* Retrieve a single {@link java.math.BigDecimal} from a result set. The result set must have
128+
* only one column and one or zero rows. The column must be retrievable from the result set
129+
* via the ResultSet.getBigDecimal() method.
130+
*
131+
* @param selectStatement the select statement
132+
* @return the extracted value. The Optional will be empty if zero rows are returned, or if the returned
133+
* column is null
134+
*/
135+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
136+
Optional<BigDecimal> selectOptionalBigDecimal(SelectStatementProvider selectStatement);
137+
138+
/**
139+
* Retrieve a List of {@link java.math.BigDecimal} from a result set. The result set must have
140+
* only one column, but can have any number of rows. The column must be retrievable from the result set
141+
* via the ResultSet.getBigDecimal() method.
142+
*
143+
* @param selectStatement the select statement
144+
* @return the list of extracted values. Any value may be null if a column in the result set is null
145+
*/
146+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
147+
List<BigDecimal> selectManyBigDecimals(SelectStatementProvider selectStatement);
148+
149+
/**
150+
* Retrieve a single {@link java.lang.Double} from a result set. The result set must have
151+
* only one column and one or zero rows. The column must be retrievable from the result set
152+
* via the ResultSet.getDouble() method.
153+
*
154+
* @param selectStatement the select statement
155+
* @return the extracted value. May be null if zero rows are returned, or if the returned
156+
* column is null
157+
*/
158+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
159+
Double selectOneDouble(SelectStatementProvider selectStatement);
160+
161+
/**
162+
* Retrieve a single {@link java.lang.Double} from a result set. The result set must have
163+
* only one column and one or zero rows. The column must be retrievable from the result set
164+
* via the ResultSet.getDouble() method.
165+
*
166+
* @param selectStatement the select statement
167+
* @return the extracted value. The Optional will be empty if zero rows are returned, or if the returned
168+
* column is null
169+
*/
170+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
171+
Optional<Double> selectOptionalDouble(SelectStatementProvider selectStatement);
172+
173+
/**
174+
* Retrieve a List of {@link java.lang.Double} from a result set. The result set must have
175+
* only one column, but can have any number of rows. The column must be retrievable from the result set
176+
* via the ResultSet.getDouble() method.
177+
*
178+
* @param selectStatement the select statement
179+
* @return the list of extracted values. Any value may be null if a column in the result set is null
180+
*/
181+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
182+
List<Double> selectManyDoubles(SelectStatementProvider selectStatement);
183+
184+
/**
185+
* Retrieve a single {@link java.lang.Integer} from a result set. The result set must have
186+
* only one column and one or zero rows. The column must be retrievable from the result set
187+
* via the ResultSet.getInt() method.
188+
*
189+
* @param selectStatement the select statement
190+
* @return the extracted value. May be null if zero rows are returned, or if the returned
191+
* column is null
192+
*/
193+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
194+
Integer selectOneInteger(SelectStatementProvider selectStatement);
195+
196+
/**
197+
* Retrieve a single {@link java.lang.Integer} from a result set. The result set must have
198+
* only one column and one or zero rows. The column must be retrievable from the result set
199+
* via the ResultSet.getInt() method.
200+
*
201+
* @param selectStatement the select statement
202+
* @return the extracted value. The Optional will be empty if zero rows are returned, or if the returned
203+
* column is null
204+
*/
205+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
206+
Optional<Integer> selectOptionalInteger(SelectStatementProvider selectStatement);
207+
208+
/**
209+
* Retrieve a List of {@link java.lang.Integer} from a result set. The result set must have
210+
* only one column, but can have any number of rows. The column must be retrievable from the result set
211+
* via the ResultSet.getInt() method.
212+
*
213+
* @param selectStatement the select statement
214+
* @return the list of extracted values. Any value may be null if a column in the result set is null
215+
*/
216+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
217+
List<Integer> selectManyIntegers(SelectStatementProvider selectStatement);
218+
219+
/**
220+
* Retrieve a single {@link java.lang.Long} from a result set. The result set must have
221+
* only one column and one or zero rows. The column must be retrievable from the result set
222+
* via the ResultSet.getLong() method.
223+
*
224+
* @param selectStatement the select statement
225+
* @return the extracted value. May be null if zero rows are returned, or if the returned
226+
* column is null
227+
*/
228+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
229+
Long selectOneLong(SelectStatementProvider selectStatement);
230+
231+
/**
232+
* Retrieve a single {@link java.lang.Long} from a result set. The result set must have
233+
* only one column and one or zero rows. The column must be retrievable from the result set
234+
* via the ResultSet.getLong() method.
235+
*
236+
* @param selectStatement the select statement
237+
* @return the extracted value. The Optional will be empty if zero rows are returned, or if the returned
238+
* column is null
239+
*/
240+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
241+
Optional<Long> selectOptionalLong(SelectStatementProvider selectStatement);
242+
243+
/**
244+
* Retrieve a List of {@link java.lang.Long} from a result set. The result set must have
245+
* only one column, but can have any number of rows. The column must be retrievable from the result set
246+
* via the ResultSet.getLong() method.
247+
*
248+
* @param selectStatement the select statement
249+
* @return the list of extracted values. Any value may be null if a column in the result set is null
250+
*/
251+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
252+
List<Long> selectManyLongs(SelectStatementProvider selectStatement);
253+
254+
/**
255+
* Retrieve a single {@link java.lang.String} from a result set. The result set must have
256+
* only one column and one or zero rows. The column must be retrievable from the result set
257+
* via the ResultSet.getString() method.
258+
*
259+
* @param selectStatement the select statement
260+
* @return the extracted value. May be null if zero rows are returned, or if the returned
261+
* column is null
262+
*/
263+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
264+
String selectOneString(SelectStatementProvider selectStatement);
265+
266+
/**
267+
* Retrieve a single {@link java.lang.String} from a result set. The result set must have
268+
* only one column and one or zero rows. The column must be retrievable from the result set
269+
* via the ResultSet.getString() method.
270+
*
271+
* @param selectStatement the select statement
272+
* @return the extracted value. The Optional will be empty if zero rows are returned, or if the returned
273+
* column is null
274+
*/
275+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
276+
Optional<String> selectOptionalString(SelectStatementProvider selectStatement);
277+
278+
/**
279+
* Retrieve a List of {@link java.lang.String} from a result set. The result set must have
280+
* only one column, but can have any number of rows. The column must be retrievable from the result set
281+
* via the ResultSet.getString() method.
282+
*
283+
* @param selectStatement the select statement
284+
* @return the list of extracted values. Any value may be null if a column in the result set is null
285+
*/
286+
@SelectProvider(type = SqlProviderAdapter.class, method = "select")
287+
List<String> selectManyStrings(SelectStatementProvider selectStatement);
288+
}

0 commit comments

Comments
 (0)