Skip to content

Commit c7b2fde

Browse files
romanseyraffaelstein
authored andcommitted
Add support for streamed query results.
Use queryForStream for streamed query results. ResultSetExtractor is ignored because it cannot be used together with streams. Original pull request spring-projects#176 Closes spring-projects#356
1 parent ba65318 commit c7b2fde

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

Diff for: spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.data.jdbc.repository.query;
1717

1818
import java.util.List;
19+
import java.util.stream.Stream;
1920

2021
import org.springframework.dao.EmptyResultDataAccessException;
2122
import org.springframework.data.repository.query.RepositoryQuery;
@@ -89,10 +90,14 @@ protected JdbcQueryExecution<?> getQueryExecution(JdbcQueryMethod queryMethod,
8990
return createModifyingQueryExecutor();
9091
}
9192

92-
if (queryMethod.isCollectionQuery() || queryMethod.isStreamQuery()) {
93+
if (queryMethod.isCollectionQuery()) {
9394
return extractor != null ? getQueryExecution(extractor) : collectionQuery(rowMapper);
9495
}
9596

97+
if (queryMethod.isStreamQuery()) {
98+
return streamQuery(rowMapper);
99+
}
100+
96101
return extractor != null ? getQueryExecution(extractor) : singleObjectQuery(rowMapper);
97102
}
98103

@@ -123,6 +128,10 @@ private <T> JdbcQueryExecution<List<T>> collectionQuery(RowMapper<T> rowMapper)
123128
return getQueryExecution(new RowMapperResultSetExtractor<>(rowMapper));
124129
}
125130

131+
private <T> JdbcQueryExecution<Stream<T>> streamQuery(RowMapper<T> rowMapper) {
132+
return (query, parameters) -> operations.queryForStream(query, parameters, rowMapper);
133+
}
134+
126135
private <T> JdbcQueryExecution<T> getQueryExecution(ResultSetExtractor<T> resultSetExtractor) {
127136
return (query, parameters) -> operations.query(query, parameters, resultSetExtractor);
128137
}

Diff for: spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java

+19
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,21 @@ public void executeCustomQueryWithReturnTypeIsStream() {
170170
.containsExactlyInAnyOrder("a", "b");
171171
}
172172

173+
@Test // DATAJDBC-356
174+
public void executeCustomQueryWithNamedParameterAndReturnTypeIsStream() {
175+
176+
repository.save(dummyEntity("a"));
177+
repository.save(dummyEntity("b"));
178+
repository.save(dummyEntity("c"));
179+
180+
Stream<DummyEntity> entities = repository.findByNamedRangeWithNamedParameterAndReturnTypeIsStream("a", "c");
181+
182+
assertThat(entities) //
183+
.extracting(e -> e.name) //
184+
.containsExactlyInAnyOrder("b");
185+
186+
}
187+
173188
@Test // DATAJDBC-175
174189
public void executeCustomQueryWithReturnTypeIsNumber() {
175190

@@ -289,6 +304,10 @@ private interface DummyEntityRepository extends CrudRepository<DummyEntity, Long
289304
@Query("SELECT * FROM DUMMY_ENTITY")
290305
Stream<DummyEntity> findAllWithReturnTypeIsStream();
291306

307+
@Query("SELECT * FROM DUMMY_ENTITY WHERE name < :upper and name > :lower")
308+
Stream<DummyEntity> findByNamedRangeWithNamedParameterAndReturnTypeIsStream(@Param("lower") String lower,
309+
@Param("upper") String upper);
310+
292311
// DATAJDBC-175
293312
@Query("SELECT count(*) FROM DUMMY_ENTITY WHERE name like concat('%', :name, '%')")
294313
int countByNameContaining(@Param("name") String name);

Diff for: spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.springframework.jdbc.core.ResultSetExtractor;
3636
import org.springframework.jdbc.core.RowMapper;
3737
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
38+
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
3839

3940
/**
4041
* Unit tests for {@link StringBasedJdbcQuery}.
@@ -151,6 +152,17 @@ public void customResultSetExtractorAndRowMapperGetCombined() {
151152
"RowMapper is not expected to be custom");
152153
}
153154

155+
@Test // DATAJDBC-356
156+
void streamQueryCallsQueryForStreamOnOperations() {
157+
doReturn(true).when(queryMethod).isStreamQuery();
158+
doReturn("some sql statement").when(queryMethod).getDeclaredQuery();
159+
160+
StringBasedJdbcQuery subject = createQuery();
161+
subject.execute(new Object[] {});
162+
163+
verify(operations).queryForStream(eq("some sql statement"), any(SqlParameterSource.class), eq(defaultRowMapper));
164+
}
165+
154166
/**
155167
* The whole purpose of this method is to easily generate a {@link DefaultParameters} instance during test setup.
156168
*/

0 commit comments

Comments
 (0)