Skip to content

Commit 36fafb2

Browse files
authored
Merge pull request #255 from jeffgbutler/general-mapper
Add MyBatis Utility Mapper for Any Query
2 parents 32ab4b0 + 314de11 commit 36fafb2

File tree

15 files changed

+1083
-205
lines changed

15 files changed

+1083
-205
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=miles
1313
### Added
1414

1515
- Added a callback capability to the "In" conditions that will be called before rendering when the conditions are empty. Also, removed the option that forced the library to render invalid SQL in that case. ([#241](https://github.com/mybatis/mybatis-dynamic-sql/pull/241))
16+
- Added a utility mapper for MyBatis that allows you to run any select query without having to predefine a result mapping. ([#255](https://github.com/mybatis/mybatis-dynamic-sql/pull/255))
1617

1718
## Release 1.2.0 - August 19, 2020
1819

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

0 commit comments

Comments
 (0)