Browse Source

Add documentation for streaming results.

Also us Github issue numbers on tests.

Original pull request #903
See #578, #971
pull/1002/head
Jens Schauder 5 years ago
parent
commit
377d841284
No known key found for this signature in database
GPG Key ID: 45CC872F17423DBF
  1. 2
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java
  2. 33
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java
  3. 14
      src/main/asciidoc/jdbc.adoc
  4. 9
      src/main/asciidoc/new-features.adoc

2
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/QueryAnnotationHsqlIntegrationTests.java

@ -174,7 +174,7 @@ public class QueryAnnotationHsqlIntegrationTests { @@ -174,7 +174,7 @@ public class QueryAnnotationHsqlIntegrationTests {
.containsExactlyInAnyOrder("a", "b");
}
@Test // DATAJDBC-356
@Test // GH-578
public void executeCustomQueryWithNamedParameterAndReturnTypeIsStream() {
repository.save(dummyEntity("a"));

33
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java

@ -40,7 +40,6 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext @@ -40,7 +40,6 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries;
import org.springframework.data.repository.query.DefaultParameters;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
@ -57,8 +56,7 @@ import org.springframework.util.ReflectionUtils; @@ -57,8 +56,7 @@ import org.springframework.util.ReflectionUtils;
* @author Mark Paluch
* @author Dennis Effing
*/
public class StringBasedJdbcQueryUnitTests {
class StringBasedJdbcQueryUnitTests {
RowMapper<Object> defaultRowMapper;
NamedParameterJdbcOperations operations;
@ -66,7 +64,7 @@ public class StringBasedJdbcQueryUnitTests { @@ -66,7 +64,7 @@ public class StringBasedJdbcQueryUnitTests {
JdbcConverter converter;
@BeforeEach
public void setup() throws NoSuchMethodException {
void setup() throws NoSuchMethodException {
this.defaultRowMapper = mock(RowMapper.class);
this.operations = mock(NamedParameterJdbcOperations.class);
@ -75,17 +73,16 @@ public class StringBasedJdbcQueryUnitTests { @@ -75,17 +73,16 @@ public class StringBasedJdbcQueryUnitTests {
}
@Test // DATAJDBC-165
public void emptyQueryThrowsException() {
void emptyQueryThrowsException() {
JdbcQueryMethod queryMethod = createMethod("noAnnotation");
Assertions.assertThatExceptionOfType(IllegalStateException.class) //
.isThrownBy(() -> createQuery(queryMethod)
.execute(new Object[] {}));
.isThrownBy(() -> createQuery(queryMethod).execute(new Object[] {}));
}
@Test // DATAJDBC-165
public void defaultRowMapperIsUsedByDefault() {
void defaultRowMapperIsUsedByDefault() {
JdbcQueryMethod queryMethod = createMethod("findAll");
StringBasedJdbcQuery query = createQuery(queryMethod);
@ -94,7 +91,7 @@ public class StringBasedJdbcQueryUnitTests { @@ -94,7 +91,7 @@ public class StringBasedJdbcQueryUnitTests {
}
@Test // DATAJDBC-165, DATAJDBC-318
public void customRowMapperIsUsedWhenSpecified() {
void customRowMapperIsUsedWhenSpecified() {
JdbcQueryMethod queryMethod = createMethod("findAllWithCustomRowMapper");
StringBasedJdbcQuery query = createQuery(queryMethod);
@ -103,7 +100,7 @@ public class StringBasedJdbcQueryUnitTests { @@ -103,7 +100,7 @@ public class StringBasedJdbcQueryUnitTests {
}
@Test // DATAJDBC-290
public void customResultSetExtractorIsUsedWhenSpecified() {
void customResultSetExtractorIsUsedWhenSpecified() {
JdbcQueryMethod queryMethod = createMethod("findAllWithCustomResultSetExtractor");
StringBasedJdbcQuery query = createQuery(queryMethod);
@ -117,7 +114,7 @@ public class StringBasedJdbcQueryUnitTests { @@ -117,7 +114,7 @@ public class StringBasedJdbcQueryUnitTests {
}
@Test // DATAJDBC-290
public void customResultSetExtractorAndRowMapperGetCombined() {
void customResultSetExtractorAndRowMapperGetCombined() {
JdbcQueryMethod queryMethod = createMethod("findAllWithCustomRowMapperAndResultSetExtractor");
StringBasedJdbcQuery query = createQuery(queryMethod);
@ -131,8 +128,9 @@ public class StringBasedJdbcQueryUnitTests { @@ -131,8 +128,9 @@ public class StringBasedJdbcQueryUnitTests {
"RowMapper is not expected to be custom");
}
@Test // DATAJDBC-356
public void streamQueryCallsQueryForStreamOnOperations() {
@Test // GH-578
void streamQueryCallsQueryForStreamOnOperations() {
JdbcQueryMethod queryMethod = createMethod("findAllWithStreamReturnType");
StringBasedJdbcQuery query = createQuery(queryMethod);
@ -141,20 +139,21 @@ public class StringBasedJdbcQueryUnitTests { @@ -141,20 +139,21 @@ public class StringBasedJdbcQueryUnitTests {
verify(operations).queryForStream(eq("some sql statement"), any(SqlParameterSource.class), any(RowMapper.class));
}
@Test // DATAJDBC-356
@Test // GH-578
void streamQueryFallsBackToCollectionQueryWhenCustomResultSetExtractorIsSpecified() {
JdbcQueryMethod queryMethod = createMethod("findAllWithStreamReturnTypeAndResultSetExtractor");
StringBasedJdbcQuery query = createQuery(queryMethod);
query.execute(new Object[] {});
ArgumentCaptor<ResultSetExtractor> captor = ArgumentCaptor.forClass(ResultSetExtractor.class);
ArgumentCaptor<ResultSetExtractor<?>> captor = ArgumentCaptor.forClass(ResultSetExtractor.class);
verify(operations).query(eq("some sql statement"), any(SqlParameterSource.class), captor.capture());
assertThat(captor.getValue()).isInstanceOf(CustomResultSetExtractor.class);
}
@Test // GH-774
public void sliceQueryNotSupported() {
void sliceQueryNotSupported() {
JdbcQueryMethod queryMethod = createMethod("sliceAll", Pageable.class);
@ -164,7 +163,7 @@ public class StringBasedJdbcQueryUnitTests { @@ -164,7 +163,7 @@ public class StringBasedJdbcQueryUnitTests {
}
@Test // GH-774
public void pageQueryNotSupported() {
void pageQueryNotSupported() {
JdbcQueryMethod queryMethod = createMethod("pageAll", Pageable.class);

14
src/main/asciidoc/jdbc.adoc

@ -466,6 +466,8 @@ interface PersonRepository extends PagingAndSortingRepository<Person, String> { @@ -466,6 +466,8 @@ interface PersonRepository extends PagingAndSortingRepository<Person, String> {
@Query("SELECT * FROM person WHERE lastname = :lastname")
List<Person> findByLastname(String lastname); <7>
@Query("SELECT * FROM person WHERE lastname = :lastname")
Stream<Person> streamByLastname(String lastname); <8>
}
----
<1> The method shows a query for all people with the given `lastname`.
@ -478,6 +480,7 @@ Thus, the method name results in a query expression of `SELECT … FROM person W @@ -478,6 +480,7 @@ Thus, the method name results in a query expression of `SELECT … FROM person W
It completes with `IncorrectResultSizeDataAccessException` on non-unique results.
<6> In contrast to <3>, the first entity is always emitted even if the query yields more result documents.
<7> The `findByLastname` method shows a query for all people with the given last name.
<8> The `streamByLastname` method returns a `Stream` which makes values possible as soon as they are returned from the database.
====
The following table shows the keywords that are supported for query methods:
@ -622,6 +625,17 @@ Named queries are expected to be provided in the property file `META-INF/jdbc-na @@ -622,6 +625,17 @@ Named queries are expected to be provided in the property file `META-INF/jdbc-na
The location of that file may be changed by setting a value to `@EnableJdbcRepositories.namedQueriesLocation`.
[[jdbc.query-methods.at-query.streaming-results]]
==== Streaming Results
When you specify `Stream` as the return type of a query method Spring Data JDBC will return elements as soon as they become available.
When dealing with large amounts of data this is suitable for reducing latency and memory requirements.
The stream contains an open connection to the database.
To avoid memory leaks that connection needs to be closed eventually by closing the stream.
The recommended way to do that is a try-with-resource clause.
It also means once the connection to the database is closed, the stream cannot obtain further elements and will likely throw an exception.
[[jdbc.query-methods.at-query.custom-rowmapper]]
==== Custom `RowMapper`

9
src/main/asciidoc/new-features.adoc

@ -3,8 +3,15 @@ @@ -3,8 +3,15 @@
This section covers the significant changes for each version.
[[new-features.2-3-0]]
== What's New in Spring Data JDBC 2.3
* Support for <<jdbc.query-methods.at-query.streaming-results, streaming results>>.
* Support for specifying projection types as return type or using generics and providing a Class parameter to query methods.
[[new-features.2-2-0]]
== `Page` and `Slice` support for <<jdbc.query-methods,derived queries>>.
== What's New in Spring Data JDBC 2.2
* `Page` and `Slice` support for <<jdbc.query-methods,derived queries>>.
[[new-features.2-1-0]]
== What's New in Spring Data JDBC 2.1

Loading…
Cancel
Save