Skip to content

Commit 12dc98b

Browse files
committed
#2 - Polishing.
1 parent ce0a707 commit 12dc98b

28 files changed

+247
-746
lines changed

README.adoc

Lines changed: 157 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,196 @@
1-
image:https://spring.io/badges/spring-data-jdbc/ga.svg["Spring Data JDBC", link="https://spring.io/projects/spring-data-jdbc#learn"]
2-
image:https://spring.io/badges/spring-data-jdbc/snapshot.svg["Spring Data JDBC", link="https://spring.io/projects/spring-data-jdbc#learn"]
1+
= Spring Data R2DBC
32

4-
= Spring Data JDBC
3+
The primary goal of the http://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use data access technologies. *Spring Data R2DBC* offers the popular Repository abstraction based on https://r2dbc.io[R2DBC].
54

6-
The primary goal of the http://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use data access technologies. *Spring Data JDBC* offers the popular Repository abstraction based on JDBC.
5+
R2DBC is the abbreviation for https://github.com/r2dbc/[Reactive Relational Database Connectivity], an incubator to integrate relational databases using a reactive driver.
76

8-
It aims at being conceptually easy.
9-
In order to achieve this it does NOT offer caching, lazy loading, write behind or many other features of JPA.
10-
This makes Spring Data JDBC a simple, limited, opinionated ORM.
7+
The state of R2DBC is incubating to evaluate how an reactive integration could look like. To get started, you need a R2DBC driver first.
118

12-
== Features
9+
== This is NOT an ORM
1310

14-
* Implementation of CRUD methods for Aggregates.
15-
* `@Query` annotation
16-
* Support for transparent auditing (created, last changed)
17-
* Events for persistence events
18-
* Possibility to integrate custom repository code
19-
* JavaConfig based repository configuration by introducing `EnableJdbcRepository`
20-
* Integration with MyBatis
11+
Spring Data R2DBC does not try to be an ORM.
12+
Instead it is more of a construction kit for your personal reactive relational data access component that you can define the way you like or need it.
2113

22-
== Getting Help
14+
== Maven Coordinates
2315

24-
If you are new to Spring Data JDBC read the following two articles https://spring.io/blog/2018/09/17/introducing-spring-data-jdbc["Introducing Spring Data JDBC"] and https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates["Spring Data JDBC, References, and Aggregates"]
16+
[source,xml]
17+
----
18+
<dependency>
19+
<groupId>org.springframework.data</groupId>
20+
<artifactId>spring-data-r2dbc</artifactId>
21+
<version>1.0.0.BUILD-SNAPSHOT</version>
22+
</dependency>
23+
----
2524

26-
There are also examples in the https://github.com/spring-projects/spring-data-examples/tree/master/jdbc[Spring Data Examples] project.
2725

28-
A very good source of information is the source code in this repository.
29-
Especially the integration tests (if you are reading this on github, type `t` and then `IntegrationTests.java`)
26+
== DatabaseClient
3027

31-
We are keeping an eye on the (soon to be created) https://stackoverflow.com/questions/tagged/spring-data-jdbc[spring-data-jdbc tag on stackoverflow].
28+
All functionality is encapsulated in `DatabaseClient` which is the entry point for applications that wish to integrate with relational databases using reactive drivers:
3229

33-
If you think you found a bug, or have a feature request please https://jira.spring.io/browse/DATAJDBC/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panel[create a ticket in our issue tracker].
30+
[source,java]
31+
----
32+
PostgresqlConnectionFactory connectionFactory = new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder()
33+
.host(…)
34+
.database(…)
35+
.username(…)
36+
.password(…).build());
37+
38+
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);
39+
----
3440

35-
== Execute Tests
41+
The client API provides covers the following features:
3642

37-
=== Fast running tests
43+
* Execution of generic SQL and consumption of update count/row results.
44+
* Generic `SELECT` with paging and ordering.
45+
* `SELECT` of mapped objects with paging and ordering.
46+
* Generic `INSERT` with parameter binding.
47+
* `INSERT` of mapped objects.
48+
* Parameter binding using the native syntax.
49+
* Result consumption: Update count, unmapped (`Map<String, Object>`), mapped to entities, extraction function.
50+
* Reactive repositories using `@Query` annotated methods.
51+
* Transaction Management.
3852

39-
Fast running tests can be executed with a simple
53+
=== Examples executing generic SQL statements
4054

41-
[source]
55+
[source,java]
4256
----
43-
mvn test
57+
Mono<Integer> count = databaseClient.execute()
58+
.sql("INSERT INTO legoset (id, name, manual) VALUES($1, $2, $3)")
59+
.bind("$1", 42055)
60+
.bind("$2", "Description")
61+
.bindNull("$3", Integer.class)
62+
.fetch()
63+
.rowsUpdated();
64+
65+
Flux<Map<String, Object>> rows = databaseClient.execute()
66+
.sql("SELECT id, name, manual FROM legoset")
67+
.fetch().all();
68+
69+
Flux<Long> result = db.execute()
70+
.sql("SELECT txid_current();")
71+
.exchange()
72+
.flatMapMany(it -> it.extract((r, md) -> r.get(0, Long.class)).all());
4473
----
4574

46-
This will execute unit tests and integration tests using an in-memory database.
75+
=== Examples selecting data
4776

48-
=== Running tests with a real database
77+
[source,java]
78+
----
79+
80+
Flux<Map<String, Object>> rows = databaseClient.select()
81+
.from("legoset")
82+
.orderBy(Sort.by(desc("id")))
83+
.fetch()
84+
.all();
85+
86+
Flux<LegoSet> rows = databaseClient.select()
87+
.from("legoset")
88+
.orderBy(Sort.by(desc("id")))
89+
.as(LegoSet.class)
90+
.fetch()
91+
.all();
92+
----
4993

50-
In order to run the integration tests against a specific database you need to have a local Docker installation available, and then execute.
94+
=== Examples inserting data
5195

52-
[source]
96+
[source,java]
5397
----
54-
mvn test -Dspring.profiles.active=<databasetype>
98+
Flux<Integer> ids = databaseClient.insert()
99+
.into("legoset")
100+
.value("id", 42055)
101+
.value("name", "Description")
102+
.nullValue("manual", Integer.class)
103+
.exchange() //
104+
.flatMapMany(it -> it.extract((r, m) -> r.get("id", Integer.class)).all())
105+
106+
Flux<Integer> ids = databaseClient.insert()
107+
.into(LegoSet.class)
108+
.using(legoSet)
109+
.exchange()
110+
.flatMapMany(it -> it.extract((r, m) -> r.get("id", Integer.class)).all())
55111
----
56112

57-
This will also execute the unit tests.
113+
=== Examples using reactive repositories
58114

59-
Currently the following _databasetypes_ are available:
115+
[source,java]
116+
----
117+
interface LegoSetRepository extends ReactiveCrudRepository<LegoSet, Integer> {
60118
61-
* hsql (default, does not require a running database)
62-
* mysql
63-
* postgres
64-
* mariadb
119+
@Query("SELECT * FROM legoset WHERE name like $1")
120+
Flux<LegoSet> findByNameContains(String name);
65121
66-
=== Run tests with all databases
122+
@Query("SELECT * FROM legoset WHERE manual = $1")
123+
Mono<LegoSet> findByManual(int manual);
124+
}
125+
----
126+
127+
=== Examples using transaction control
67128

68-
[source]
129+
All examples above run with auto-committed transactions. To get group multiple statements within the same transaction or
130+
control the transaction yourself, you need to use `TransactionalDatabaseClient`:
131+
132+
[source,java]
69133
----
70-
mvn test -Pall-dbs
134+
TransactionalDatabaseClient databaseClient = TransactionalDatabaseClient.create(connectionFactory);
71135
----
72136

73-
This will execute the unit tests, and all the integration tests with all the databases we currently support for testing. Running the integration-tests depends on Docker.
137+
`TransactionalDatabaseClient` allows multiple flavors of transaction management:
138+
139+
* Participate in ongoing transactions and fall-back to auto-commit mode if there's no active transaction (default).
140+
* Group multiple statements in a managed transaction using `TransactionalDatabaseClient.inTransaction(…)`.
141+
* Application-controlled transaction management using `TransactionalDatabaseClient.beginTransaction()`/`commitTransaction()`/`rollbackTransaction()`.
74142

75-
== Contributing to Spring Data JDBC
143+
Participating in ongoing transactions does not require changes to your application code. Instead, a managed transaction must be hosted by your application container. Transaction control needs to happen there, as well.
144+
145+
**Statement grouping**
146+
147+
[source,java]
148+
----
149+
Flux<Integer> rowsUpdated = databaseClient.inTransaction(db -> {
150+
151+
return db.execute().sql("INSERT INTO legoset (id, name, manual) VALUES($1, $2, $3)") //
152+
.bind(0, 42055) //
153+
.bind(1, "Description") //
154+
.bindNull("$3", Integer.class) //
155+
.fetch()
156+
.rowsUpdated();
157+
});
158+
----
159+
160+
**Application-controlled transaction management**
161+
162+
[source,java]
163+
----
164+
Flux<Long> txId = databaseClient.execute().sql("SELECT txid_current();").exchange()
165+
.flatMapMany(it -> it.extract((r, md) -> r.get(0, Long.class)).all());
166+
167+
Mono<Void> then = databaseClient.enableTransactionSynchronization(databaseClient.beginTransaction() //
168+
.thenMany(txId)) //
169+
.then(databaseClient.rollbackTransaction()));
170+
----
171+
172+
NOTE: Application-controlled transactions must be enabled with `enableTransactionSynchronization(…)`.
173+
174+
== Building from Source
175+
176+
You don't need to build from source to use Spring Data R2DBC (binaries in https://repo.spring.io[repo.spring.io]), but if you want to try out the latest and greatest, Spring Data R2DBC can be easily built with the https://github.com/takari/maven-wrapper[maven wrapper]. You also need JDK 1.8.
177+
178+
[indent=0]
179+
----
180+
$ ./mvnw clean install
181+
----
182+
183+
If you want to build with the regular `mvn` command, you will need https://maven.apache.org/run-maven/index.html[Maven v3.5.0 or above].
184+
185+
_Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular please fill out the https://cla.pivotal.io/[Contributor's Agreement] before your first change._
186+
187+
== Contributing to Spring Data R2DBC
76188

77189
Here are some ways for you to get involved in the community:
78190

79-
* Get involved with the Spring community by helping out on http://stackoverflow.com/questions/tagged/spring-data-jdbc[stackoverflow] by responding to questions and joining the debate.
80-
* Create https://jira.spring.io/browse/DATAJDBC[JIRA] tickets for bugs and new features and comment and vote on the ones that you are interested in.
191+
* Get involved with the Spring community by helping out on http://stackoverflow.com/questions/tagged/spring-data-r2dbc[Stackoverflow] by responding to questions and joining the debate.
192+
* Create https://github.com/spring-data/spring-data-r2dbc[GitHub] tickets for bugs and new features and comment and vote on the ones that you are interested in.
81193
* Github is for social coding: if you want to write code, we encourage contributions through pull requests from http://help.github.com/forking/[forks of this repository]. If you want to contribute code this way, please reference a JIRA ticket as well, covering the specific issue you are addressing.
82194
* Watch for upcoming articles on Spring by http://spring.io/blog[subscribing] to spring.io.
83195

84196
Before we accept a non-trivial patch or pull request we will need you to https://cla.pivotal.io/sign/spring[sign the Contributor License Agreement]. Signing the contributor’s agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. If you forget to do so, you'll be reminded when you submit a pull request. Active contributors might be asked to join the core team, and given the ability to merge pull requests.
85-
86-
== License
87-
88-
link:src/main/resources/license.txt[The license und which Spring Data JDBC is published can be found here].

0 commit comments

Comments
 (0)