Skip to content

Commit

Permalink
docs: document JDBC connection tips and performance considerations (#233
Browse files Browse the repository at this point in the history
)

Adds tips and performance considerations for connecting with the native
PostgreSQL JDBC driver.
  • Loading branch information
olavloite authored Jul 1, 2022
1 parent eeed030 commit 5a09690
Showing 1 changed file with 76 additions and 4 deletions.
80 changes: 76 additions & 4 deletions docs/jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,54 @@ First start PGAdapter:

```shell
wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz && tar -xzvf pgadapter.tar.gz
java -jar pgadapter.jar -p my-project -i my-instance -d my-database
java -jar pgadapter.jar -p my-project -i my-instance
```

Connect to PGAdapter like this:
Connect to PGAdapter using TCP like this:

```java
// Make sure the PG JDBC driver is loaded.
Class.forName("org.postgresql.Driver");

// Replace localhost and 5432 with the host and port number where PGAdapter is running.
// prepareThreshold=0 disables the use of server-side prepared statements in JDBC.
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/?prepareThreshold=0")) {
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/my-database")) {
try (ResultSet resultSet = connection.createStatement().executeQuery("select 'Hello world!' as hello")) {
while (resultSet.next()) {
System.out.printf("Greeting from Cloud Spanner PostgreSQL: %s\n", resultSet.getString(1));
}
}
}
```


### Unix Domain Sockets
Connect to PGAdapter using Unix Domain Sockets like this:

Add this to your dependencies:
```xml
<dependency>
<groupId>com.kohlschutter.junixsocket</groupId>
<artifactId>junixsocket-core</artifactId>
<version>2.5.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.kohlschutter.junixsocket</groupId>
<artifactId>junixsocket-common</artifactId>
<version>2.5.0</version>
</dependency>
```

```java
// Make sure the PG JDBC driver is loaded.
Class.forName("org.postgresql.Driver");

// '/tmp' is the default domain socket directory for PGAdapter. This can be changed using the -dir
// command line argument. 5432 is the default port number used by PGAdapter. Change this in the
// connection string if PGAdapter is running on a custom port.
try (Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost/my-database"
+ "?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg"
+ "&socketFactoryArg=/tmp/.s.PGSQL.5432")) {
try (ResultSet resultSet = connection.createStatement().executeQuery("select 'Hello world!' as hello")) {
while (resultSet.next()) {
System.out.printf("Greeting from Cloud Spanner PostgreSQL: %s\n", resultSet.getString(1));
Expand All @@ -33,3 +69,39 @@ try (Connection connection = DriverManager.getConnection("jdbc:postgresql://loca

This example uses the pre-built jar to run PGAdapter as a standalone process.
See [README](../README.md) for more possibilities on how to run PGAdapter.

## Performance Considerations

The following will give you the best possible performance when using the JDBC driver with PGAdapter.

### Unix Domain Sockets
Use Unix Domain Socket connections for the lowest possible latency when PGAdapter and the client
application are running on the same host. See https://jdbc.postgresql.org/documentation/head/connect.html
for more information on connection options for the JDBC driver.

### JDBC Batching
Use the JDBC batching API when executing multiple DDL or DML statements. PGAdapter will combine
DML and DDL statements that are executed in a JDBC batch into a single request on Cloud Spanner.
This can significantly reduce the overhead of executing multiple DML or DDL statements.

Example for DML statements:

```java
try (java.sql.Statement statement = connection.createStatement()) {
statement.addBatch("insert into my_table (key, value) values ('k1', 'value1')");
statement.addBatch("insert into my_table (key, value) values ('k2', 'value2')");
// This will execute the above statements as a single batch DML request on Cloud Spanner.
int[] updateCounts = statement.executeBatch();
}
```

Example for DDL statements:

```java
try (java.sql.Statement statement = connection.createStatement()) {
statement.addBatch("create table singers (singerid varchar primary key, name varchar)");
statement.addBatch("create index idx_singers_name on singers (name)");
// This will execute the above statements as a single DDL update request on Cloud Spanner.
int[] updateCounts = statement.executeBatch();
}
```

0 comments on commit 5a09690

Please sign in to comment.