Skip to content

Commit 020d46b

Browse files
committed
#282 - Add documentation.
Original pull request: #295.
1 parent 4e5bf95 commit 020d46b

File tree

3 files changed

+120
-10
lines changed

3 files changed

+120
-10
lines changed

Diff for: src/main/asciidoc/index.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ include::reference/kotlin.adoc[leveloffset=+1]
4646
= Appendix
4747

4848
:numbered!:
49+
include::{spring-data-commons-docs}/repository-query-keywords-reference.adoc[leveloffset=+1]
4950
include::{spring-data-commons-docs}/repository-query-return-types-reference.adoc[leveloffset=+1]

Diff for: src/main/asciidoc/new-features.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
== What's New in Spring Data R2DBC 1.1.0 RELEASE
66

77
* Introduction of `R2dbcEntityTemplate` for entity-oriented operations.
8+
* <<r2dbc.repositories.queries,Query derivation>>.
89
* Support interface projections with `DatabaseClient.as(…)`.
910
* <<r2dbc.datbaseclient.filter,Support for `ExecuteFunction` and `StatementFilterFunction` via `DatabaseClient.filter(…)`>>.
1011

Diff for: src/main/asciidoc/reference/r2dbc-repositories.adoc

+118-10
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@ The following example shows a repository interface for the preceding `Person` cl
3535
====
3636
[source]
3737
----
38-
public interface PersonRepository extends ReactiveCrudRepository<Person, Long> {
38+
public interface PersonRepository extends PagingAndSortingRepository<Person, String> {
3939
4040
// additional custom query methods go here
4141
}
4242
----
4343
====
4444

45-
Right now, this interface provides only type information, but we can add additional methods to it later.
4645
To configure R2DBC repositories, you can use the `@EnableR2dbcRepositories` annotation.
4746
If no base package is configured, the infrastructure scans the package of the annotated configuration class.
4847
The following example shows how to use Java configuration for a repository:
@@ -85,6 +84,15 @@ public class PersonRepositoryTests {
8584
.expectNextCount(1)
8685
.verifyComplete();
8786
}
87+
88+
@Test
89+
public void readsEntitiesByNameCorrectly() {
90+
91+
repository.findByFirstname("Hello World")
92+
.as(StepVerifier::create)
93+
.expectNextCount(1)
94+
.verifyComplete();
95+
}
8896
}
8997
----
9098
====
@@ -103,25 +111,125 @@ Defining such a query is a matter of declaring a method on the repository interf
103111
====
104112
[source,java]
105113
----
106-
public interface PersonRepository extends ReactiveCrudRepository<Person, Long> {
114+
interface ReactivePersonRepository extends ReactiveSortingRepository<Person, String> {
115+
116+
Flux<Person> findByFirstname(String firstname); <1>
117+
118+
Flux<Person> findByFirstname(Publisher<String> firstname); <2>
119+
120+
Flux<Person> findByFirstnameOrderByLastname(String firstname, Pageable pageable); <3>
121+
122+
Mono<Person> findByFirstnameAndLastname(String firstname, String lastname); <4>
123+
124+
Mono<Person> findFirstByLastname(String lastname); <5>
107125
108126
@Query("SELECT * FROM person WHERE lastname = :lastname")
109-
Flux<Person> findByLastname(String lastname); <1>
127+
Flux<Person> findByLastname(String lastname); <6>
110128
111129
@Query("SELECT firstname, lastname FROM person WHERE lastname = $1")
112-
Mono<Person> findFirstByLastname(String lastname) <2>
113-
130+
Mono<Person> findFirstByLastname(String lastname); <7>
114131
}
115132
----
116-
<1> The `findByLastname` method shows a query for all people with the given last name.
133+
<1> The method shows a query for all people with the given `lastname`. The query is derived by parsing the method name for constraints that can be concatenated with `And` and `Or`. Thus, the method name results in a query expression of `SELECT … FROM person WHERE firstname = :firstname`.
134+
<2> The method shows a query for all people with the given `firstname` once the `firstname` is emitted by the given `Publisher`.
135+
<3> Use `Pageable` to pass offset and sorting parameters to the database.
136+
<4> Find a single entity for the given criteria. It completes with `IncorrectResultSizeDataAccessException` on non-unique results.
137+
<5> Unless <4>, the first entity is always emitted even if the query yields more result documents.
138+
<6> The `findByLastname` method shows a query for all people with the given last name.
117139
The query is provided, as R2DBC repositories do not support query derivation.
118-
<2> A query for a single `Person` entity projecting only `firstname` and `lastname` columns.
140+
<7> A query for a single `Person` entity projecting only `firstname` and `lastname` columns.
119141
The annotated query uses native bind markers, which are Postgres bind markers in this example.
120142
====
121143

122-
NOTE: R2DBC repositories do not support query derivation.
144+
The following table shows the keywords that are supported for query methods:
145+
146+
[cols="1,2,3", options="header", subs="quotes"]
147+
.Supported keywords for query methods
148+
|===
149+
| Keyword
150+
| Sample
151+
| Logical result
152+
153+
| `After`
154+
| `findByBirthdateAfter(Date date)`
155+
| `birthdate > date`
156+
157+
| `GreaterThan`
158+
| `findByAgeGreaterThan(int age)`
159+
| `age > age`
160+
161+
| `GreaterThanEqual`
162+
| `findByAgeGreaterThanEqual(int age)`
163+
| `age >= age`
164+
165+
| `Before`
166+
| `findByBirthdateBefore(Date date)`
167+
| `birthdate < date`
168+
169+
| `LessThan`
170+
| `findByAgeLessThan(int age)`
171+
| `age < age`
172+
173+
| `LessThanEqual`
174+
| `findByAgeLessThanEqual(int age)`
175+
| `age <= age`
176+
177+
| `Between`
178+
| `findByAgeBetween(int from, int to)`
179+
| `age BETWEEN from AND to`
180+
181+
| `NotBetween`
182+
| `findByAgeBetween(int from, int to)`
183+
| `age NOT BETWEEN from AND to`
184+
185+
| `In`
186+
| `findByAgeIn(Collection<Integer> ages)`
187+
| `age IN (age1, age2, ageN)`
188+
189+
| `NotIn`
190+
| `findByAgeNotIn(Collection ages)`
191+
| `age NOT IN (age1, age2, ageN)`
192+
193+
| `IsNotNull`, `NotNull`
194+
| `findByFirstnameNotNull()`
195+
| `firstname IS NOT NULL`
196+
197+
| `IsNull`, `Null`
198+
| `findByFirstnameNull()`
199+
| `firstname IS NULL`
200+
201+
| `Like`, `StartingWith`, `EndingWith`
202+
| `findByFirstnameLike(String name)`
203+
| `firstname LIKE name`
204+
205+
| `NotLike`, `IsNotLike`
206+
| `findByFirstnameNotLike(String name)`
207+
| `firstname NOT LIKE name`
208+
209+
| `Containing` on String
210+
| `findByFirstnameContaining(String name)`
211+
| `firstname LIKE '%' + name +'%'`
212+
213+
| `NotContaining` on String
214+
| `findByFirstnameNotContaining(String name)`
215+
| `firstname NOT LIKE '%' + name +'%'`
216+
217+
| `(No keyword)`
218+
| `findByFirstname(String name)`
219+
| `firstname = name`
220+
221+
| `Not`
222+
| `findByFirstnameNot(String name)`
223+
| `firstname != name`
224+
225+
| `IsTrue`, `True`
226+
| `findByActiveIsTrue()`
227+
| `active IS TRUE`
123228

124-
NOTE: R2DBC repositories internally bind parameters to placeholders with `Statement.bind(…)` by index.
229+
| `IsFalse`, `False`
230+
| `findByActiveIsFalse()`
231+
| `active IS FALSE`
232+
|===
125233

126234
[[r2dbc.repositories.modifying]]
127235
=== Modifying Queries

0 commit comments

Comments
 (0)