@@ -11,11 +11,13 @@ specification effort to standardize access to SQL databases using reactive patte
11
11
The Spring Framework's R2DBC abstraction framework consists of two different packages:
12
12
13
13
* `core`: The `org.springframework.r2dbc.core` package contains the `DatabaseClient`
14
- class plus a variety of related classes. See xref:data-access/r2dbc.adoc#r2dbc-core[Using the R2DBC Core Classes to Control Basic R2DBC Processing and Error Handling].
14
+ class plus a variety of related classes. See
15
+ xref:data-access/r2dbc.adoc#r2dbc-core[Using the R2DBC Core Classes to Control Basic R2DBC Processing and Error Handling].
15
16
16
17
* `connection`: The `org.springframework.r2dbc.connection` package contains a utility class
17
18
for easy `ConnectionFactory` access and various simple `ConnectionFactory` implementations
18
- that you can use for testing and running unmodified R2DBC. See xref:data-access/r2dbc.adoc#r2dbc-connections[Controlling Database Connections].
19
+ that you can use for testing and running unmodified R2DBC. See
20
+ xref:data-access/r2dbc.adoc#r2dbc-connections[Controlling Database Connections].
19
21
20
22
21
23
[[r2dbc-core]]
@@ -31,6 +33,7 @@ including error handling. It includes the following topics:
31
33
* xref:data-access/r2dbc.adoc#r2dbc-DatabaseClient-filter[Statement Filters]
32
34
* xref:data-access/r2dbc.adoc#r2dbc-auto-generated-keys[Retrieving Auto-generated Keys]
33
35
36
+
34
37
[[r2dbc-DatabaseClient]]
35
38
=== Using `DatabaseClient`
36
39
@@ -43,8 +46,9 @@ SQL and extract results. The `DatabaseClient` class:
43
46
* Runs SQL queries
44
47
* Update statements and stored procedure calls
45
48
* Performs iteration over `Result` instances
46
- * Catches R2DBC exceptions and translates them to the generic, more informative, exception
47
- hierarchy defined in the `org.springframework.dao` package. (See xref:data-access/dao.adoc#dao-exceptions[Consistent Exception Hierarchy].)
49
+ * Catches R2DBC exceptions and translates them to the generic, more informative,
50
+ exception hierarchy defined in the `org.springframework.dao` package.
51
+ (See xref:data-access/dao.adoc#dao-exceptions[Consistent Exception Hierarchy].)
48
52
49
53
The client has a functional, fluent API using reactive types for declarative composition.
50
54
@@ -250,7 +254,6 @@ Kotlin::
250
254
----
251
255
======
252
256
253
-
254
257
[[r2dbc-DatabaseClient-mapping-null]]
255
258
.What about `null`?
256
259
****
@@ -315,10 +318,10 @@ The following example shows parameter binding for a query:
315
318
316
319
[source,java]
317
320
----
318
- db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
319
- .bind("id", "joe")
320
- .bind("name", "Joe")
321
- .bind("age", 34);
321
+ db.sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
322
+ .bind("id", "joe")
323
+ .bind("name", "Joe")
324
+ .bind("age", 34);
322
325
----
323
326
324
327
.R2DBC Native Bind Markers
@@ -327,7 +330,7 @@ R2DBC uses database-native bind markers that depend on the actual database vendo
327
330
As an example, Postgres uses indexed markers, such as `$1`, `$2`, `$n`.
328
331
Another example is SQL Server, which uses named bind markers prefixed with `@`.
329
332
330
- This is different from JDBC, which requires `?` as bind markers.
333
+ This is different from JDBC which requires `?` as bind markers.
331
334
In JDBC, the actual drivers translate `?` bind markers to database-native
332
335
markers as part of their statement execution.
333
336
@@ -363,7 +366,7 @@ Java::
363
366
tuples.add(new Object[] {"Ann", 50});
364
367
365
368
client.sql("SELECT id, name, state FROM table WHERE (name, age) IN (:tuples)")
366
- .bind("tuples", tuples);
369
+ .bind("tuples", tuples);
367
370
----
368
371
369
372
Kotlin::
@@ -375,7 +378,7 @@ Kotlin::
375
378
tuples.add(arrayOf("Ann", 50))
376
379
377
380
client.sql("SELECT id, name, state FROM table WHERE (name, age) IN (:tuples)")
378
- .bind("tuples", tuples)
381
+ .bind("tuples", tuples)
379
382
----
380
383
======
381
384
@@ -390,7 +393,7 @@ Java::
390
393
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
391
394
----
392
395
client.sql("SELECT id, name, state FROM table WHERE age IN (:ages)")
393
- .bind("ages", Arrays.asList(35, 50));
396
+ .bind("ages", Arrays.asList(35, 50));
394
397
----
395
398
396
399
Kotlin::
@@ -402,7 +405,7 @@ Kotlin::
402
405
tuples.add(arrayOf("Ann", 50))
403
406
404
407
client.sql("SELECT id, name, state FROM table WHERE age IN (:ages)")
405
- .bind("tuples", arrayOf(35, 50))
408
+ .bind("tuples", arrayOf(35, 50))
406
409
----
407
410
======
408
411
@@ -429,19 +432,19 @@ Java::
429
432
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
430
433
----
431
434
client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
432
- .filter((s, next) -> next.execute(s.returnGeneratedValues("id")))
433
- .bind("name", …)
434
- .bind("state", …);
435
+ .filter((s, next) -> next.execute(s.returnGeneratedValues("id")))
436
+ .bind("name", …)
437
+ .bind("state", …);
435
438
----
436
439
437
440
Kotlin::
438
441
+
439
442
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
440
443
----
441
444
client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
442
- .filter { s: Statement, next: ExecuteFunction -> next.execute(s.returnGeneratedValues("id")) }
443
- .bind("name", …)
444
- .bind("state", …)
445
+ .filter { s: Statement, next: ExecuteFunction -> next.execute(s.returnGeneratedValues("id")) }
446
+ .bind("name", …)
447
+ .bind("state", …)
445
448
----
446
449
======
447
450
@@ -455,21 +458,21 @@ Java::
455
458
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
456
459
----
457
460
client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
458
- .filter(statement -> s.returnGeneratedValues("id"));
461
+ .filter(statement -> s.returnGeneratedValues("id"));
459
462
460
463
client.sql("SELECT id, name, state FROM table")
461
- .filter(statement -> s.fetchSize(25));
464
+ .filter(statement -> s.fetchSize(25));
462
465
----
463
466
464
467
Kotlin::
465
468
+
466
469
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
467
470
----
468
471
client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
469
- .filter { statement -> s.returnGeneratedValues("id") }
472
+ .filter { statement -> s.returnGeneratedValues("id") }
470
473
471
474
client.sql("SELECT id, name, state FROM table")
472
- .filter { statement -> s.fetchSize(25) }
475
+ .filter { statement -> s.fetchSize(25) }
473
476
----
474
477
======
475
478
@@ -593,7 +596,7 @@ Java::
593
596
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
594
597
----
595
598
Mono<Integer> generatedId = client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
596
- .filter(statement -> s.returnGeneratedValues("id"))
599
+ .filter(statement -> s.returnGeneratedValues("id"))
597
600
.map(row -> row.get("id", Integer.class))
598
601
.first();
599
602
@@ -605,7 +608,7 @@ Kotlin::
605
608
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
606
609
----
607
610
val generatedId = client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
608
- .filter { statement -> s.returnGeneratedValues("id") }
611
+ .filter { statement -> s.returnGeneratedValues("id") }
609
612
.map { row -> row.get("id", Integer.class) }
610
613
.awaitOne()
611
614
@@ -672,7 +675,6 @@ Kotlin::
672
675
[[r2dbc-ConnectionFactoryUtils]]
673
676
=== Using `ConnectionFactoryUtils`
674
677
675
-
676
678
The `ConnectionFactoryUtils` class is a convenient and powerful helper class
677
679
that provides `static` methods to obtain connections from `ConnectionFactory`
678
680
and close connections (if necessary).
0 commit comments