Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,19 @@ activate the `shade` profile like this:
mvn package -Pshade
```



## Samples

See the [samples](/samples) directory for various examples for using the Spanner JDBC driver.

- [snippets](/samples/snippets): Contains small code snippets for commonly used JDBC and Spanner
features. Refer to these snippets for examples on how to execute DDL and DML batches, use various
data types with the JDBC driver, execute various types of transactions (read/write, read-only,
Partitioned DML), use request and transaction tags, etc.
- [spring-data-jdbc](/samples/spring-data-jdbc): Contains a sample application that uses Spring Data
JDBC in combination with a Spanner PostgreSQL database.
- [spring-data-mybatis](/samples/spring-data-mybatis): Contains a sample application that uses
Spring Data MyBatis in combination with a Spanner PostgreSQL database.
- [quickperf](/samples/quickperf): Contains a simple benchmarking application.


## Troubleshooting
Expand Down
1 change: 1 addition & 0 deletions samples/snapshot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<groupId>com.google.cloud.samples</groupId>
<artifactId>shared-configuration</artifactId>
<version>1.2.2</version>
<relativePath/>
</parent>

<properties>
Expand Down
7 changes: 7 additions & 0 deletions samples/snippets/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<excludes>**/SingerProto.java</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.example.spanner.jdbc;

import com.example.spanner.jdbc.SingerProto.Genre;
import com.example.spanner.jdbc.SingerProto.SingerInfo;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.cloud.spanner.DatabaseId;
Expand All @@ -29,13 +31,17 @@
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminSettings;
import com.google.cloud.spanner.jdbc.CloudSpannerJdbcConnection;
import com.google.cloud.spanner.jdbc.ProtoEnumType;
import com.google.cloud.spanner.jdbc.ProtoMessageType;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.spanner.admin.database.v1.CreateDatabaseRequest;
import com.google.spanner.admin.database.v1.DatabaseDialect;
import com.google.spanner.admin.instance.v1.InstanceName;
import com.google.spanner.v1.DatabaseName;
import io.grpc.ManagedChannelBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
Expand Down Expand Up @@ -1576,6 +1582,98 @@ static void arrayOfStructAsQueryParameter(
}
}

static void protoColumns(
final String project,
final String instance,
final String database,
final Properties properties) throws SQLException, IOException {
try (Connection connection =
DriverManager.getConnection(
String.format(
"jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s",
project, instance, database),
properties)) {
// Create a PROTO BUNDLE and a table.
try (Statement statement = connection.createStatement();
InputStream protoDescriptors = JdbcSample.class.getClassLoader()
.getResourceAsStream("com/example/spanner/jdbc/descriptors.pb")) {
if (protoDescriptors == null) {
throw new IllegalArgumentException("proto descriptors not found");
}

// Unwrap the CloudSpannerJdbcConnection interface to set the proto
// descriptors that should be used for the next DDL statements.
connection
.unwrap(CloudSpannerJdbcConnection.class)
.setProtoDescriptors(protoDescriptors);
// Execute the DDL statements as one batch.
// This will reduce execution time compared to executing each statement
// sequentially.
statement.addBatch("CREATE PROTO BUNDLE (\n"
+ "examples.spanner.music.SingerInfo,\n"
+ "examples.spanner.music.Genre,\n"
+ ")");
statement.addBatch("CREATE TABLE SingersWithProto (\n"
+ " SingerId INT64 NOT NULL,\n"
+ " SingerInfo examples.spanner.music.SingerInfo,\n"
+ " SingerGenre examples.spanner.music.Genre,\n"
+ ") PRIMARY KEY (SingerId)");
statement.executeBatch();
}

// Insert a couple of rows using a prepared statement.
try (PreparedStatement statement = connection.prepareStatement(
"INSERT INTO SingersWithProto "
+ "(SingerId, SingerInfo, SingerGenre) "
+ "VALUES (?, ?, ?)")) {
int param = 0;
statement.setLong(++param, 1L);
statement.setObject(++param,
SingerInfo.newBuilder()
.setGenre(Genre.ROCK)
.setBirthDate("1998-07-04")
.setSingerId(1L)
.setNationality("ES")
.build(), ProtoMessageType.VENDOR_TYPE_NUMBER);
statement.setObject(++param, Genre.ROCK,
ProtoEnumType.VENDOR_TYPE_NUMBER);
statement.addBatch();

param = 0;
statement.setLong(++param, 2L);
statement.setObject(++param,
SingerInfo.newBuilder()
.setGenre(Genre.POP)
.setBirthDate("2001-12-03")
.setSingerId(2L)
.setNationality("FO")
.build(), ProtoMessageType.VENDOR_TYPE_NUMBER);
statement.setObject(++param, Genre.POP,
ProtoEnumType.VENDOR_TYPE_NUMBER);
statement.addBatch();

int[] updateCounts = statement.executeBatch();
System.out.printf("Inserted %d singers\n",
Arrays.stream(updateCounts).sum());
}

// Read the inserted rows.
try (ResultSet resultSet = connection.createStatement()
.executeQuery("SELECT * FROM SingersWithProto")) {
while (resultSet.next()) {
long singerId = resultSet.getLong("SingerId");
// Proto messages and proto enums can be retrieved with the
// ResultSet#getObject(int, Class) method.
// The Spanner JDBC driver automatically deserializes
// and converts the column to the Java class representation.
SingerInfo info = resultSet.getObject("SingerInfo", SingerInfo.class);
Genre genre = resultSet.getObject("SingerGenre", Genre.class);
System.out.printf("%d:\n%s\n%s\n", singerId, info, genre);
}
}
}
}

/** The expected number of command line arguments. */
private static final int NUM_EXPECTED_ARGS = 3;

Expand Down Expand Up @@ -1761,6 +1859,13 @@ static boolean runGoogleSQLSample(
database.getDatabase(),
createProperties());
return true;
case "protocolumns":
protoColumns(
database.getInstanceId().getProject(),
database.getInstanceId().getInstance(),
database.getDatabase(),
createProperties());
return true;
default:
return false;
}
Expand Down
Loading