Skip to content

Commit 7e98925

Browse files
committed
Introduce Stream variant methods for SqlQuery
Closes GH-34474 Signed-off-by: Yanming Zhou <[email protected]>
1 parent cacc63d commit 7e98925

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java

+44
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.List;
2020
import java.util.Map;
21+
import java.util.stream.Stream;
2122

2223
import javax.sql.DataSource;
2324

@@ -52,6 +53,7 @@
5253
* @author Rod Johnson
5354
* @author Juergen Hoeller
5455
* @author Thomas Risberg
56+
* @author Yanming Zhou
5557
* @param <T> the result type
5658
* @see SqlUpdate
5759
*/
@@ -94,6 +96,23 @@ public List<T> execute(Object @Nullable [] params, @Nullable Map<?, ?> context)
9496
return getJdbcTemplate().query(newPreparedStatementCreator(params), rowMapper);
9597
}
9698

99+
/**
100+
* Central execution method for Stream. All un-named parameter execution goes through this method.
101+
* @param params parameters, similar to JDO query parameters.
102+
* Primitive parameters must be represented by their Object wrapper type.
103+
* The ordering of parameters is significant.
104+
* @param context the contextual information passed to the {@code mapRow}
105+
* callback method. The JDBC operation itself doesn't rely on this parameter,
106+
* but it can be useful for creating the objects of the result list.
107+
* @return a result Stream of objects, one per row of the ResultSet. Normally all these
108+
* will be of the same class, although it is possible to use different types.
109+
*/
110+
public Stream<T> executeForStream(Object @Nullable [] params, @Nullable Map<?, ?> context) throws DataAccessException {
111+
validateParameters(params);
112+
RowMapper<T> rowMapper = newRowMapper(params, context);
113+
return getJdbcTemplate().queryForStream(newPreparedStatementCreator(params), rowMapper);
114+
}
115+
97116
/**
98117
* Convenient method to execute without context.
99118
* @param params parameters for the query. Primitive parameters must
@@ -104,6 +123,16 @@ public List<T> execute(Object... params) throws DataAccessException {
104123
return execute(params, null);
105124
}
106125

126+
/**
127+
* Convenient method to execute for Stream without context.
128+
* @param params parameters for the query. Primitive parameters must
129+
* be represented by their Object wrapper type. The ordering of parameters is
130+
* significant.
131+
*/
132+
public Stream<T> executeForStream(Object... params) throws DataAccessException {
133+
return executeForStream(params, null);
134+
}
135+
107136
/**
108137
* Convenient method to execute without parameters.
109138
* @param context the contextual information for object creation
@@ -112,13 +141,28 @@ public List<T> execute(Map<?, ?> context) throws DataAccessException {
112141
return execute((Object[]) null, context);
113142
}
114143

144+
/**
145+
* Convenient method to execute for Stream without parameters.
146+
* @param context the contextual information for object creation
147+
*/
148+
public Stream<T> executeForStream(Map<?, ?> context) throws DataAccessException {
149+
return executeForStream((Object[]) null, context);
150+
}
151+
115152
/**
116153
* Convenient method to execute without parameters nor context.
117154
*/
118155
public List<T> execute() throws DataAccessException {
119156
return execute((Object[]) null, null);
120157
}
121158

159+
/**
160+
* Convenient method to execute for Stream without parameters nor context.
161+
*/
162+
public Stream<T> executeForStream() throws DataAccessException {
163+
return executeForStream((Object[]) null, null);
164+
}
165+
122166
/**
123167
* Convenient method to execute with a single int parameter and context.
124168
* @param p1 single int parameter

spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java

+28
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.HashMap;
2727
import java.util.List;
2828
import java.util.Map;
29+
import java.util.stream.Stream;
2930

3031
import javax.sql.DataSource;
3132

@@ -52,6 +53,7 @@
5253
* @author Trevor Cook
5354
* @author Thomas Risberg
5455
* @author Juergen Hoeller
56+
* @author Yanming Zhou
5557
*/
5658
class SqlQueryTests {
5759

@@ -125,6 +127,32 @@ protected Integer mapRow(ResultSet rs, int rownum, Object @Nullable [] params, @
125127
verify(preparedStatement).close();
126128
}
127129

130+
@Test
131+
void testQueryForStreamWithoutParams() throws SQLException {
132+
given(resultSet.next()).willReturn(true, false);
133+
given(resultSet.getInt(1)).willReturn(1);
134+
135+
SqlQuery<Integer> query = new MappingSqlQueryWithParameters<>() {
136+
@Override
137+
protected Integer mapRow(ResultSet rs, int rownum, Object @Nullable [] params, @Nullable Map<? ,?> context)
138+
throws SQLException {
139+
assertThat(params).as("params were null").isNull();
140+
assertThat(context).as("context was null").isNull();
141+
return rs.getInt(1);
142+
}
143+
};
144+
query.setDataSource(dataSource);
145+
query.setSql(SELECT_ID);
146+
query.compile();
147+
try (Stream<Integer> stream = query.executeForStream()) {
148+
List<Integer> list = stream.toList();
149+
assertThat(list).containsExactly(1);
150+
}
151+
verify(connection).prepareStatement(SELECT_ID);
152+
verify(resultSet).close();
153+
verify(preparedStatement).close();
154+
}
155+
128156
@Test
129157
void testQueryWithoutEnoughParams() {
130158
MappingSqlQuery<Integer> query = new MappingSqlQuery<>() {

0 commit comments

Comments
 (0)