Skip to content

Commit 970d55e

Browse files
committed
Add documentation for DB2 client
1 parent 4b05f19 commit 970d55e

File tree

2 files changed

+253
-28
lines changed

2 files changed

+253
-28
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
= Reactive DB2 Client
2+
:PREPARED_PARAMS: `?`​
3+
4+
The Reactive DB2 Client is a client for DB2 with a straightforward API focusing on
5+
scalability and low overhead.
6+
7+
The client is reactive and non blocking, allowing to handle many database connections with a single thread.
8+
9+
*Features*
10+
11+
* Support for DB2 on Linux, Unix, and Windows
12+
* Limited support for DB2 on z/OS
13+
* Event driven
14+
* Lightweight
15+
* Built-in connection pooling
16+
* Prepared queries caching
17+
* Batch and cursor
18+
* Row streaming
19+
* RxJava 1 and RxJava 2
20+
* Direct memory to object without unnecessary copies
21+
* Java 8 Date and Time
22+
* HTTP/1.x CONNECT, SOCKS4a or SOCKS5 proxy support
23+
24+
*Current limitations*
25+
26+
* No TLS/SSL support
27+
* No stored procedures support
28+
* Some column types (e.g. BLOB and CLOB) are not supported
29+
30+
== Usage
31+
32+
To use the Reactive DB2 Client add the following dependency to the _dependencies_ section of your build descriptor:
33+
34+
* Maven (in your `pom.xml`):
35+
36+
[source,xml]
37+
----
38+
<dependency>
39+
<groupId>${maven.groupId}</groupId>
40+
<artifactId>${maven.artifactId}</artifactId>
41+
<version>${maven.version}</version>
42+
</dependency>
43+
----
44+
* Gradle (in your `build.gradle` file):
45+
46+
[source,groovy]
47+
----
48+
dependencies {
49+
compile '${maven.groupId}:${maven.artifactId}:${maven.version}'
50+
}
51+
----
52+
53+
== Getting started
54+
55+
Here is the simplest way to connect, query and disconnect
56+
57+
[source,$lang]
58+
----
59+
{@link examples.DB2ClientExamples#gettingStarted()}
60+
----
61+
62+
== Connecting to DB2
63+
64+
Most of the time you will use a pool to connect to DB2:
65+
66+
[source,$lang]
67+
----
68+
{@link examples.DB2ClientExamples#connecting01}
69+
----
70+
71+
The pooled client uses a connection pool and any operation will borrow a connection from the pool
72+
to execute the operation and release it to the pool.
73+
74+
If you are running with Vert.x you can pass it your Vertx instance:
75+
76+
[source,$lang]
77+
----
78+
{@link examples.DB2ClientExamples#connecting02}
79+
----
80+
81+
You need to release the pool when you don't need it anymore:
82+
83+
[source,$lang]
84+
----
85+
{@link examples.DB2ClientExamples#connecting03}
86+
----
87+
88+
When you need to execute several operations on the same connection, you need to use a client
89+
{@link io.vertx.db2client.DB2Connection connection}.
90+
91+
You can easily get one from the pool:
92+
93+
[source,$lang]
94+
----
95+
{@link examples.DB2ClientExamples#connecting04}
96+
----
97+
98+
Once you are done with the connection you must close it to release it to the pool, so it can be reused.
99+
100+
== Configuration
101+
102+
There are several alternatives for you to configure the client.
103+
104+
=== data object
105+
106+
A simple way to configure the client is to specify a `DB2ConnectOptions` data object.
107+
108+
[source,$lang]
109+
----
110+
{@link examples.DB2ClientExamples#configureFromDataObject(io.vertx.core.Vertx)}
111+
----
112+
113+
You can also configure the generic properties with the `setProperties` or `addProperty` methods. Note `setProperties` will override the default client properties.
114+
115+
=== connection uri
116+
117+
Apart from configuring with a `DB2ConnectOptions` data object, We also provide you an alternative way to connect when you want to configure with a connection URI:
118+
119+
[source,$lang]
120+
----
121+
{@link examples.DB2ClientExamples#configureFromUri(io.vertx.core.Vertx)}
122+
----
123+
124+
The URI format for a connection string is:
125+
126+
----
127+
db2://<USERNAME>:<PASSWORD>@<HOSTNAME>:<PORT>/<DBNAME>
128+
----
129+
130+
Currently the client supports the following parameter key words in connection uri
131+
132+
* host
133+
* port
134+
* user
135+
* password
136+
* dbname
137+
138+
Note: configuring properties in connection URI will override the default properties.
139+
140+
include::queries.adoc[]
141+
142+
You can fetch generated keys by wrapping your query in `SELECT <COLUMNS> FROM FINAL TABLE ( <SQL> )`, for example:
143+
144+
[source,$lang]
145+
----
146+
{@link examples.DB2ClientExamples#generatedKeys(io.vertx.sqlclient.SqlClient)}
147+
----
148+
149+
include::connections.adoc[]
150+
151+
include::transactions.adoc[]
152+
153+
include::cursor.adoc[]
154+
155+
== DB2 type mapping
156+
157+
Currently the client supports the following DB2 types
158+
159+
* BOOLEAN (`java.lang.Boolean`) (DB2 LUW only)
160+
* SMALLINT (`java.lang.Short`)
161+
* INTEGER (`java.lang.Integer`)
162+
* BIGINT (`java.lang.Long`)
163+
* REAL (`java.lang.Float`)
164+
* DOUBLE (`java.lang.Double`)
165+
* DECIMAL (`io.vertx.sqlclient.data.Numeric`)
166+
* CHAR (`java.lang.String`)
167+
* VARCHAR (`java.lang.String`)
168+
* DATE (`java.time.LocalDate`)
169+
* TIME (`java.time.LocalTime`)
170+
* TIMESTAMP (`java.time.LocalDateTime`)
171+
* BINARY (`byte[]`)
172+
* VARBINARY (`byte[]`)
173+
* ROWID (`io.vertx.db2client.impl.drda.DB2RowId` or `java.sql.RowId`) (DB2 z/OS only)
174+
175+
Some types that are currently NOT supported are:
176+
177+
* XML
178+
* BLOB
179+
* CLOB
180+
* DBCLOB
181+
* GRAPHIC / VARGRAPHIC
182+
183+
For a further documentation on DB2 data types, see the following resources:
184+
185+
* https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0008483.html[DB2 for LUW 11.5 data types]
186+
* https://www.ibm.com/support/knowledgecenter/SSEPEK_12.0.0/sqlref/src/tpc/db2z_datatypesintro.html[DB2 for z/OS 12.0 data types]
187+
188+
Tuple decoding uses the above types when storing values, it also performs on the fly conversion of the actual value when possible:
189+
190+
[source,$lang]
191+
----
192+
{@link examples.DB2ClientExamples#typeMapping01}
193+
----
194+
195+
== Collector queries
196+
197+
You can use Java collectors with the query API:
198+
199+
[source,$lang]
200+
----
201+
{@link examples.DB2ClientExamples#collector01Example}
202+
----
203+
204+
The collector processing must not keep a reference on the {@link io.vertx.sqlclient.Row} as
205+
there is a single row used for processing the entire set.
206+
207+
The Java `Collectors` provides many interesting predefined collectors, for example you can
208+
create easily create a string directly from the row set:
209+
210+
[source,$lang]
211+
----
212+
{@link examples.DB2ClientExamples#collector02Example}
213+
----
214+
215+
== Using a proxy
216+
217+
You can also configure the client to use an HTTP/1.x CONNECT, SOCKS4a or SOCKS5 proxy.
218+
219+
More information can be found in the http://vertx.io/docs/vertx-core/java/#_using_a_proxy_for_client_connections[Vert.x documentation].
220+
221+
ifeval::["$lang" == "java"]
222+
include::override/rxjava2.adoc[]
223+
endif::[]

vertx-db2-client/src/main/java/examples/DB2ClientExamples.java

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,15 @@
2121
import java.util.stream.Collectors;
2222

2323
import io.vertx.core.Vertx;
24-
import io.vertx.core.json.JsonObject;
2524
import io.vertx.db2client.DB2ConnectOptions;
2625
import io.vertx.db2client.DB2Connection;
2726
import io.vertx.db2client.DB2Pool;
2827
import io.vertx.docgen.Source;
28+
import io.vertx.sqlclient.Pool;
2929
import io.vertx.sqlclient.PoolOptions;
3030
import io.vertx.sqlclient.Row;
3131
import io.vertx.sqlclient.RowSet;
3232
import io.vertx.sqlclient.SqlClient;
33-
import io.vertx.sqlclient.SqlConnection;
3433
import io.vertx.sqlclient.SqlResult;
3534
import io.vertx.sqlclient.Tuple;
3635
import io.vertx.sqlclient.data.Numeric;
@@ -199,7 +198,7 @@ public void connecting05(Vertx vertx) {
199198
.setUser("user")
200199
.setPassword("secret");
201200

202-
// Connect to Postgres
201+
// Connect to DB2
203202
DB2Connection.connect(vertx, options)
204203
.compose(conn -> {
205204
System.out.println("Connected");
@@ -224,33 +223,36 @@ public void connecting05(Vertx vertx) {
224223
}
225224
});
226225
}
227-
228-
public void jsonExample() {
229-
230-
// Create a tuple
231-
Tuple tuple = Tuple.of(
232-
Tuple.JSON_NULL,
233-
new JsonObject().put("foo", "bar"),
234-
3);
235-
236-
// Retrieving json
237-
Object value = tuple.getValue(0); // Expect JSON_NULL
238-
239-
//
240-
value = tuple.get(JsonObject.class, 1); // Expect JSON object
241-
242-
//
243-
value = tuple.get(Integer.class, 2); // Expect 3
244-
value = tuple.getInteger(2); // Expect 3
226+
227+
public void generatedKeys(SqlClient client) {
228+
client
229+
.preparedQuery("SELECT color_id FROM FINAL TABLE ( INSERT INTO color (color_name) VALUES (?), (?), (?) )")
230+
.execute(Tuple.of("white", "red", "blue"), ar -> {
231+
if (ar.succeeded()) {
232+
RowSet<Row> rows = ar.result();
233+
System.out.println("Inserted " + rows.rowCount() + " new rows.");
234+
for (Row row : rows) {
235+
System.out.println("generated key: " + row.getInteger("color_id"));
236+
}
237+
} else {
238+
System.out.println("Failure: " + ar.cause().getMessage());
239+
}
240+
});
245241
}
242+
243+
public void typeMapping01(Pool pool) {
244+
pool
245+
.query("SELECT an_int_column FROM exampleTable")
246+
.execute(ar -> {
247+
RowSet<Row> rowSet = ar.result();
248+
Row row = rowSet.iterator().next();
249+
250+
// Stored as INTEGER column type and represented as java.lang.Integer
251+
Object value = row.getValue(0);
246252

247-
public void numericExample(Row row) {
248-
Numeric numeric = row.get(Numeric.class, 0);
249-
if (numeric.isNaN()) {
250-
// Handle NaN
251-
} else {
252-
BigDecimal value = numeric.bigDecimalValue();
253-
}
253+
// Convert to java.lang.Long
254+
Long longValue = row.getLong(0);
255+
});
254256
}
255257

256258
public void collector01Example(SqlClient client) {

0 commit comments

Comments
 (0)