Skip to content

Commit 46e8278

Browse files
olavloiteskuruppu
andauthored
feat: add QueryOptions samples for JDBC (GoogleCloudPlatform#2347)
* feat: add QueryOptions samples for JDBC * fix: review comments * deps: update to most recent jdbc version * Fix google-cloud-spanner-jdbc version * fix: fix test cases and jdbc version * fix: fix dependency versions * fix: use default db and instance * fix: remove unused import Co-authored-by: skuruppu <skuruppu@google.com>
1 parent 63cd70a commit 46e8278

File tree

4 files changed

+423
-0
lines changed

4 files changed

+423
-0
lines changed

spanner/jdbc/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Cloud Spanner JDBC Example
2+
3+
This sample application demonstrates using JDBC with [Google Cloud Spanner](https://cloud.google.com/spanner/).
4+
5+
## Maven
6+
7+
This sample uses the [Apache Maven][maven] build system. Before getting started, be
8+
sure to [download][maven-download] and [install][maven-install] it. When you use
9+
Maven as described here, it will automatically download the needed client
10+
libraries.
11+
12+
[maven]: https://maven.apache.org
13+
[maven-download]: https://maven.apache.org/download.cgi
14+
[maven-install]: https://maven.apache.org/install.html
15+
16+
## Setup
17+
18+
1. Follow the set-up instructions in [the documentation](https://cloud.google.com/java/docs/setup).
19+
20+
2. Enable APIs for your project.
21+
[Click here](https://console.cloud.google.com/flows/enableapi?apiid=spanner.googleapis.com&showconfirmation=true)
22+
to visit Cloud Platform Console and enable the Google Cloud Spanner API.
23+
24+
3. Create a Cloud Spanner instance and database via the Cloud Plaform Console's
25+
[Cloud Spanner section](http://console.cloud.google.com/spanner).
26+
27+
4. Enable application default credentials by running the command `gcloud auth application-default login`.
28+
29+
30+
## Run the Example
31+
32+
Run the following command on the command line in the project directory:
33+
34+
```
35+
mvn clean compile exec:java -Dexec.args="<command> my-instance my-database"
36+
```

spanner/jdbc/pom.xml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<properties>
9+
<maven.compiler.target>1.8</maven.compiler.target>
10+
<maven.compiler.source>1.8</maven.compiler.source>
11+
</properties>
12+
13+
<!--
14+
The parent pom defines common style checks and testing strategies for our samples.
15+
Removing or replacing it should not affect the execution of the samples in anyway.
16+
-->
17+
<parent>
18+
<groupId>com.google.cloud.samples</groupId>
19+
<artifactId>shared-configuration</artifactId>
20+
<version>1.0.13</version>
21+
</parent>
22+
23+
<groupId>com.example.spanner</groupId>
24+
<artifactId>cloud-spanner-jdbc</artifactId>
25+
<name>Cloud Spanner with JDBC Code Sample</name>
26+
27+
<!-- [START spanner_jdbc_dependencies] -->
28+
<dependencies>
29+
<!-- The Spanner JDBC driver dependency -->
30+
<dependency>
31+
<groupId>com.google.cloud</groupId>
32+
<artifactId>google-cloud-spanner-jdbc</artifactId>
33+
<version>1.15.0</version>
34+
</dependency>
35+
36+
<!-- Test dependencies -->
37+
<dependency>
38+
<groupId>junit</groupId>
39+
<artifactId>junit</artifactId>
40+
<version>4.13</version>
41+
<scope>test</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>com.google.truth</groupId>
45+
<artifactId>truth</artifactId>
46+
<version>1.0.1</version>
47+
<scope>test</scope>
48+
</dependency>
49+
</dependencies>
50+
<!-- [END spanner_jdbc_dependencies] -->
51+
52+
<build>
53+
<plugins>
54+
<plugin>
55+
<groupId>org.codehaus.mojo</groupId>
56+
<artifactId>exec-maven-plugin</artifactId>
57+
<version>1.6.0</version>
58+
<executions>
59+
<execution>
60+
<goals>
61+
<goal>java</goal>
62+
</goals>
63+
</execution>
64+
</executions>
65+
<configuration>
66+
<mainClass>com.example.spanner.JdbcSample</mainClass>
67+
<cleanupDaemonThreads>false</cleanupDaemonThreads>
68+
</configuration>
69+
</plugin>
70+
</plugins>
71+
</build>
72+
</project>
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*
2+
* Copyright 2020 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.spanner;
18+
19+
import com.google.cloud.spanner.SpannerOptions;
20+
import java.sql.Connection;
21+
import java.sql.DriverManager;
22+
import java.sql.PreparedStatement;
23+
import java.sql.ResultSet;
24+
import java.sql.SQLException;
25+
import java.sql.Statement;
26+
import java.sql.Types;
27+
import java.util.Arrays;
28+
import java.util.List;
29+
30+
/** Example showing how to use the Cloud Spanner open source JDBC driver. */
31+
public class JdbcSample {
32+
33+
/** Class to contain singer sample data. */
34+
static class Singer {
35+
36+
final long singerId;
37+
final String firstName;
38+
final String lastName;
39+
40+
Singer(long singerId, String firstName, String lastName) {
41+
this.singerId = singerId;
42+
this.firstName = firstName;
43+
this.lastName = lastName;
44+
}
45+
}
46+
47+
static final List<Singer> SINGERS =
48+
Arrays.asList(
49+
new Singer(1, "Marc", "Richards"),
50+
new Singer(2, "Catalina", "Smith"),
51+
new Singer(3, "Alice", "Trentor"),
52+
new Singer(4, "Lea", "Martin"),
53+
new Singer(5, "David", "Lomond"));
54+
55+
/**
56+
* This example shows how to create a JDBC connection and use this to execute queries and updates.
57+
*/
58+
public static void main(String[] args) throws Exception {
59+
if (args.length != 3) {
60+
printUsageAndExit();
61+
}
62+
63+
/*
64+
* CREATE TABLE Singers (
65+
* SingerId INT64 NOT NULL,
66+
* FirstName STRING(1024),
67+
* LastName STRING(1024),
68+
* SingerInfo BYTES(MAX),
69+
* ) PRIMARY KEY (SingerId);
70+
*/
71+
72+
String command = args[0];
73+
String projectId = SpannerOptions.getDefaultProjectId();
74+
String instanceId = args[1];
75+
String databaseId = args[2];
76+
77+
String connectionUrl =
78+
String.format(
79+
"jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s",
80+
projectId, instanceId, databaseId);
81+
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
82+
run(command, connection, projectId, instanceId, databaseId);
83+
}
84+
}
85+
86+
static void run(
87+
String command, Connection connection, String projectId, String instanceId, String databaseId)
88+
throws SQLException {
89+
switch (command) {
90+
case "createtable":
91+
createTable(connection);
92+
break;
93+
case "insertdata":
94+
insertData(connection);
95+
break;
96+
case "connectionwithqueryoptions":
97+
connectionWithQueryOptions(projectId, instanceId, databaseId);
98+
break;
99+
case "setqueryoptions":
100+
setQueryOptions(projectId, instanceId, databaseId);
101+
break;
102+
default:
103+
printUsageAndExit();
104+
}
105+
}
106+
107+
static void printUsageAndExit() {
108+
System.err.println("Usage:");
109+
System.err.println(" JdbcSample <command> <instance_id> <database_id>");
110+
System.err.println("");
111+
System.err.println("Examples:");
112+
System.err.println(" JdbcSample createtable my-instance example-db");
113+
System.err.println(" JdbcSample insertdata my-instance example-db");
114+
System.err.println(" JdbcSample connectionwithqueryoptions my-instance example-db");
115+
System.err.println(" JdbcSample setqueryoptions my-instance example-db");
116+
117+
System.exit(1);
118+
}
119+
120+
static void createTable(Connection connection) throws SQLException {
121+
try (Statement statement = connection.createStatement()) {
122+
statement.execute(
123+
"CREATE TABLE Singers (\n"
124+
+ " SingerId INT64 NOT NULL,\n"
125+
+ " FirstName STRING(1024),\n"
126+
+ " LastName STRING(1024),\n"
127+
+ " SingerInfo BYTES(MAX),\n"
128+
+ " ) PRIMARY KEY (SingerId)\n");
129+
}
130+
System.out.println("Created table [Singers]");
131+
}
132+
133+
static void insertData(Connection connection) throws SQLException {
134+
boolean originalAutoCommit = connection.getAutoCommit();
135+
connection.setAutoCommit(false);
136+
try (PreparedStatement ps =
137+
connection.prepareStatement(
138+
"INSERT INTO Singers\n"
139+
+ "(SingerId, FirstName, LastName, SingerInfo)\n"
140+
+ "VALUES\n"
141+
+ "(?, ?, ?, ?)")) {
142+
for (Singer singer : SINGERS) {
143+
ps.setLong(1, singer.singerId);
144+
ps.setString(2, singer.firstName);
145+
ps.setString(3, singer.lastName);
146+
ps.setNull(4, Types.BINARY);
147+
ps.addBatch();
148+
}
149+
int[] updateCounts = ps.executeBatch();
150+
connection.commit();
151+
System.out.printf("Insert counts: %s\n", Arrays.toString(updateCounts));
152+
} finally {
153+
connection.setAutoCommit(originalAutoCommit);
154+
}
155+
}
156+
157+
// [START spanner_jdbc_connection_with_query_options]
158+
static void connectionWithQueryOptions(String projectId, String instanceId, String databaseId)
159+
throws SQLException {
160+
String optimizerVersion = "1";
161+
String connectionUrl =
162+
String.format(
163+
"jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s?optimizerVersion=%s",
164+
projectId, instanceId, databaseId, optimizerVersion);
165+
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
166+
try (Statement statement = connection.createStatement()) {
167+
// Execute a query using the optimizer version '1'.
168+
try (ResultSet rs =
169+
statement.executeQuery(
170+
"SELECT SingerId, FirstName, LastName FROM Singers ORDER BY LastName")) {
171+
while (rs.next()) {
172+
System.out.printf("%d %s %s\n", rs.getLong(1), rs.getString(2), rs.getString(3));
173+
}
174+
}
175+
try (ResultSet rs = statement.executeQuery("SHOW VARIABLE OPTIMIZER_VERSION")) {
176+
while (rs.next()) {
177+
System.out.printf("Optimizer version: %s\n", rs.getString(1));
178+
}
179+
}
180+
}
181+
}
182+
}
183+
// [END spanner_jdbc_connection_with_query_options]
184+
185+
// [START spanner_jdbc_set_statement_for_query_options]
186+
static void setQueryOptions(String projectId, String instanceId, String databaseId)
187+
throws SQLException {
188+
String connectionUrl =
189+
String.format(
190+
"jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s",
191+
projectId, instanceId, databaseId);
192+
try (Connection connection = DriverManager.getConnection(connectionUrl)) {
193+
try (Statement statement = connection.createStatement()) {
194+
// Instruct the JDBC connection to use version '1' of the query optimizer.
195+
statement.execute("SET OPTIMIZER_VERSION='1'");
196+
// Execute a query using the latest optimizer version.
197+
try (ResultSet rs =
198+
statement.executeQuery(
199+
"SELECT SingerId, FirstName, LastName FROM Singers ORDER BY LastName")) {
200+
while (rs.next()) {
201+
System.out.printf("%d %s %s\n", rs.getLong(1), rs.getString(2), rs.getString(3));
202+
}
203+
}
204+
try (ResultSet rs = statement.executeQuery("SHOW VARIABLE OPTIMIZER_VERSION")) {
205+
while (rs.next()) {
206+
System.out.printf("Optimizer version: %s\n", rs.getString(1));
207+
}
208+
}
209+
}
210+
}
211+
}
212+
// [END spanner_jdbc_set_statement_for_query_options]
213+
214+
}

0 commit comments

Comments
 (0)