使用适用于 BigQuery 的 JDBC 驱动程序

适用于 BigQuery 的 Java Database Connectivity (JDBC) 驱动程序可将 Java 应用连接到 BigQuery,让您能够将 BigQuery 功能与首选工具和基础架构结合使用。如需将非 Java 应用连接到 BigQuery,请使用 Simba Open Database Connectivity (ODBC) 驱动程序(适用于 BigQuery)

限制

适用于 BigQuery 的 JDBC 驱动程序存在以下限制:

  • 该驱动程序专为 BigQuery 而设计,无法与其他产品或服务搭配使用。
  • BigQuery Storage Read API 不支持 INTERVAL 数据类型。
  • 所有数据操纵语言 (DML) 限制均适用。

准备工作

  1. 请确保您熟悉 JDBC 驱动程序、Apache Maven 和 java.sql 软件包
  2. 验证您的系统是否已配置 Java 运行时环境 (JRE) 8.0 或更高版本。如需了解如何检查 JRE 版本,请参阅验证 JRE 环境
  3. 向 BigQuery 进行身份验证,并记下以下信息,以便稍后在建立与 BigQuery 的 JDBC 驱动程序的连接时使用。您只需记下与您使用的身份验证方法对应的信息。

    身份验证方法 身份验证信息 示例 连接媒体资源(稍后设置)
    标准服务账号 服务账号电子邮件地址 bq-jdbc-sa@mytestproject.iam.gserviceaccount.com OAuthServiceAcctEmail
    服务账号密钥(JSON 对象) my-sa-key OAuthPvtKey
    服务账号密钥文件 服务账号密钥文件(完整路径) path/to/file/secret.json OAuthPvtKeyPath
    Google 用户账号 客户端 ID 123-abc.apps.googleusercontent.com OAuthClientId
    客户端密钥 _aB-C1D_E2fGh3Ij4kL5m6No7p8QR9sT0uV OAuthClientSecret
    预生成的访问令牌 访问令牌 ya29.a0AfH6SMCiH1L-x_yZ OAuthAccessToken
    预生成的刷新令牌 刷新令牌 1/fFAGRNJru1FTz70BzhT3Zg OAuthRefreshToken
    客户端 ID 123-abc.apps.googleusercontent.com OAuthClientId
    客户端密钥 _aB-C1D_E2fGh3Ij4kL5m6No7p8QR9sT0uV OAuthClientSecret
    应用默认凭证 不适用 不适用
    配置文件 配置文件(JSON 对象或完整路径) path/to/file/secret.json OAuthPvtKey
    外部账号配置对象 账号配置对象 external_account_configuration_object OAuthPvtKey
    其他 外部账号配置文件中的受众群体属性 //iam.googleapis.com/projects/my-project/locations/US-EAST1/workloadIdentityPools/my-pool-/providers/my-provider BYOID_AudienceUri
    令牌检索和环境信息文件 {\"file\":\"/path/to/file\"} BYOID_CredentialSource
    用户项目(仅在您使用员工池时) my_project BYOID_PoolUserProject
    服务账号模拟的 URI(仅当使用工作团队池时) my-sa BYOID_SA_Impersonation_Uri
    基于令牌交换规范的 Security Token Service 令牌 urn:ietf:params:oauth:tokentype:id_token BYOID_SubjectTokenType
    Security Token Service 令牌交换端点 https://sts.googleapis.com/v1/token BYOID_TokenUri

配置开发环境

如需使用适用于 BigQuery 的 JDBC 驱动程序配置开发环境,请执行以下操作:

  1. 下载以下 JDBC 软件包之一:

  2. 将下载的 JAR 文件添加到类路径中,以便 Java 编译器和运行时可以找到必要的 JDBC 类。如需了解如何将文件添加到类路径,请参阅设置类路径

  3. 将以下依赖项添加到您的build 文件中:

    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>google-cloud-bigquery-jdbc</artifactId>
        <version>0.0.1</version>
        <scope>system</scope>
        <systemPath>path/to/file/google-jdbc-jar-with-dependencies.jar</systemPath>
    </dependency>
  4. 如果您使用的是 Gradle 项目,请将以下内容添加到 build 文件中:

    dependencies {
    // ... other dependencies
    implementation files('path/to/file/google-jdbc-jar-with-dependencies.jar')
    }

建立连接

如需使用适用于 BigQuery 的 JDBC 驱动程序在 Java 应用与 BigQuery 之间建立连接,请执行以下操作:

  1. 确定适用于 BigQuery 的 JDBC 驱动程序的连接字符串。此字符串包含在 Java 应用与 BigQuery 之间建立连接所需的所有信息。连接字符串采用以下格式:

    jdbc:bigquery://HOST:PORT;ProjectId=PROJECT_ID;OAuthType=AUTH_TYPE;AUTH_PROPS;OTHER_PROPS

    替换以下内容:

    • HOST:服务器的 DNS 或 IP 地址。
    • PORT:TCP 端口号。
    • PROJECT_ID:BigQuery 项目的 ID。
    • AUTH_TYPE:一个数字,用于指定您使用的身份验证类型。以下项之一:
      • 0:用于服务账号身份验证(标准和密钥文件)
      • 1:用于 Google 用户账号身份验证
      • 2:用于预生成的刷新令牌或访问令牌身份验证
      • 3:用于应用默认凭据身份验证
      • 4:适用于其他身份验证方法
    • AUTH_PROPS:您在向 BigQuery 进行身份验证时记下的身份验证信息,以 property_1=value_1; property_2=value_2;... 格式列出,例如 OAuthPvtKeyPath=path/to/file/secret.json(如果您使用服务账号密钥文件进行身份验证)。
    • OTHER_PROPS(可选):JDBC 驱动程序的其他连接属性,以 property_1=value_1; property_2=value_2;... 格式列出。如需查看连接属性的完整列表,请参阅连接属性
  2. 使用 DriverManagerDataSource 类将 Java 应用连接到 BigQuery 的 JDBC 驱动程序。

    • DriverManager 类相关联:

      import java.sql.Connection;
      import java.sql.DriverManager;
      
      private static Connection getJdbcConnectionDM(){
        Connection connection = DriverManager.getConnection(CONNECTION_STRING);
        return connection;
      }

      CONNECTION_STRING 替换为上一步中的连接字符串。

    • DataSource 类相关联:

      import com.google.cloud.bigquery.jdbc.DataSource;
      import java.sql.Connection;
      import java.sql.SQLException;
      
      private static public Connection getJdbcConnectionDS() throws SQLException {
        Connection connection = null;
        DataSource dataSource = new com.google.cloud.bigquery.jdbc.DataSource();
        dataSource.setURL(CONNECTION_STRING);
        connection = dataSource.getConnection();
        return connection;
      }

      CONNECTION_STRING 替换为上一步中的连接字符串。

      DataSource 类还具有 setter 方法,您可以使用这些方法来设置连接属性,而不是将它们包含在连接字符串中。下面给出了一个示例:

      private static Connection getConnection() throws SQLException {
        DataSource ds = new DataSource();
        ds.setURL(jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;);
        ds.setAuthType(3);  // Application Default Credentials
        ds.setProjectId("MyTestProject");
        ds.setEnableHighThroughputAPI(true);
        ds.setLogLevel("6");
        ds.setUseQueryCache(false);
        return ds.getConnection();
      }

连接属性

JDBC 驱动程序连接属性是指在建立与数据库的连接时包含在连接字符串中或通过 setter 方法传递的配置参数。BigQuery 的 JDBC 驱动程序支持以下连接属性。

连接属性 说明 默认值 数据类型 必需
AdditionalProjects 驱动程序可访问以进行查询和元数据操作的项目,此外还包括通过 ProjectId 属性设置的主项目。 不适用 以逗号分隔的字符串
AllowLargeResults 确定当 QueryDialect 属性设置为 BIG_QUERY 时,驱动程序是否处理大于 128 MB 的查询结果。如果 QueryDialect 属性设置为 SQL,驱动程序将始终处理大型查询结果。 TRUE 布尔值
BYOID_AudienceUri 外部账号配置文件中的 audience 属性。受众群体属性可以包含工作负载身份池或员工池的资源名称,以及相应池中的提供方标识符。 不适用 字符串 仅当 OAuthType=4
BYOID_CredentialSource 令牌检索和环境信息。 不适用 字符串 仅当 OAuthType=4
BYOID_PoolUserProject 使用员工池进行身份验证时的用户项目。 不适用 字符串 仅当使用 OAuthType=4 且使用员工池时
BYOID_SA_Impersonation_Uri 使用工作区池进行身份验证时,服务账号模拟的 URI。 不适用 字符串 仅当使用 OAuthType=4 且使用员工池时
BYOID_SubjectTokenType 基于令牌交换规范的 Security Token Service 令牌。 以下值之一:
  • urn:ietf:params:oauth:token-type:jwt
  • urn:ietf:params:oauth:token-type:id_token
  • urn:ietf:params:oauth:token-type:saml2
  • urn:ietf:params:aws:token-type:aws4_request
urn:ietf:params:oauth:tokentype:id_token 字符串 仅当 OAuthType=4
BYOID_TokenUri Security Token Service 令牌交换端点。 https://sts.googleapis.com/v1/token 字符串
ConnectionPoolSize 连接池大小(如果已启用连接池)。 10
DefaultDataset 未在查询中指定数据集时所使用的数据集。 不适用 字符串
EnableHighThroughputAPI 确定是否可以使用 Storage Read API。HighThroughputActivationRatioHighThroughputMinTableSize 属性也必须设置为 TRUE,才能使用 Storage Read API。 FALSE 布尔值
EnableSession 确定连接是否启动会话。如果设置为 TRUE,则会将会话 ID 传递给所有后续查询。 FALSE 布尔值
EnableWriteAPI 确定是否可以使用 Storage Write API。必须将其设置为 TRUE 才能启用批量插入。 FALSE 布尔值
EndpointOverrides 用于覆盖以下内容的自定义端点:
  • BIGQUERY=https://bigquery.googleapis.com
  • READ_API=https://bigquerystorage-googleapis-com.mygreatmarket.com
  • OAUTH2=https://oauth2.googleapis.com
  • STS=https://sts.googleapis.com
不适用 以逗号分隔的字符串
FilterTablesOnDefaultDataset 确定 DatabaseMetaData.getTables()DatabaseMetaData.getColumns() 方法返回的元数据的范围。如果设置为 FALSE,则不会进行过滤。还必须设置 DefaultDataset 属性才能启用过滤功能。 FALSE 布尔值
HighThroughputActivationRatio 查询响应中的页数阈值。如果超过此数量,并且满足 EnableHighThroughputAPIHighThroughputMinTableSize 条件,驱动程序将开始使用 Storage Read API。 2 整数
HighThroughputMinTableSize 查询响应中的行数阈值。如果超过此数量,并且满足 EnableHighThroughputAPIHighThroughputActivationRatio 条件,驱动程序会开始使用 Storage Read API。 100 整数
JobCreationMode 确定查询是否在有作业的情况下运行。值为 1 表示为每个查询创建作业,值为 2 表示可以执行查询而不创建作业。 2 整数
JobTimeout 作业超时时间(以秒为单位),超过此时间后,服务器会取消作业。 0
KMSKeyName 用于加密数据的 KMS 密钥名称。 不适用 字符串
Labels 与查询关联的标签,用于整理和分组查询作业。 不适用 Map<String, String>
LargeResultDataset 大型查询结果的目标数据集,仅当设置了 LargeResultTable 属性时才有效。设置此属性后,数据写入会绕过结果缓存,并针对每个查询触发结算,即使结果很小也是如此。 _google_jdbc 字符串
LargeResultsDatasetExpirationTime 大型结果数据集中的所有表的生命周期(以毫秒为单位)。如果数据集已设置默认过期时间,则系统会忽略此属性。 3600000
LargeResultTable 大型查询结果的目标表,仅当设置了 LargeResultDataset 属性时才有效。设置此属性后,数据写入会绕过结果缓存,并针对每个查询触发结算,即使结果很小也是如此。 temp_table... 字符串
ListenerPoolSize 监听器池大小(如果已启用连接池)。 10
Location 创建或查询数据集的位置。如果未设置此属性,BigQuery 会自动确定位置。 不适用 字符串
LogLevel java.util.logging 软件包在数据库交互期间记录的详细程度。日志记录可能会影响性能,因此仅在需要捕获问题时暂时启用。以下值之一:
  • 0OFF 级别
  • 1SEVERE 级别
  • 2WARNING 级别
  • 3INFO 级别
  • 4CONFIG 级别
  • 5FINE 级别
  • 6FINER 级别
  • 7FINEST 级别
  • 8ALL 级别
0 整数
LogPath 写入日志文件的目录。 不适用 字符串
MaximumBytesBilled 结算的字节数上限。如果查询的收费字节数大于此数字,则查询会失败,但不会产生费用。 0
MaxResults 每页的结果数上限。 10000
MetaDataFetchThreadCount 用于数据库元数据方法的线程数。 32 整数
OAuthAccessToken 用于预生成的访问令牌身份验证的访问令牌。 不适用 字符串 仅当 OAUTH_TYPE=2
OAuthClientId 用于预生成的刷新令牌身份验证和用户账号身份验证的客户端 ID。 不适用 字符串 仅当 OAUTH_TYPE=1OAUTH_TYPE=2
OAuthClientSecret 用于预生成的刷新令牌身份验证和用户账号身份验证的客户端密钥。 不适用 字符串 仅当 OAUTH_TYPE=1OAUTH_TYPE=2
OAuthP12Password PKCS12 密钥文件的密码。 notasecret 字符串
OAuthPvtKey 使用服务账号身份验证时的服务账号密钥。此值可以是原始 JSON 密钥文件对象,也可以是 JSON 密钥文件的路径。 不适用 字符串 仅当 OAUTH_TYPE=0OAuthPvtKeyPath 值未设置时
OAuthPvtKeyPath 使用服务账号身份验证时,服务账号密钥的路径。 不适用 字符串 仅当未设置 OAUTH_TYPE=0 以及 OAuthPvtKeyOAuthServiceAcctEmail 值时
OAuthRefreshToken 预生成的刷新令牌身份验证的刷新令牌。 不适用 字符串 仅当 OAUTH_TYPE=2
OAuthServiceAcctEmail 使用服务账号身份验证时的服务账号电子邮件地址。 不适用 字符串 仅当 OAUTH_TYPE=0OAuthPvtKeyPath 值未设置时
OAuthType 身份验证类型。以下值之一:
  • 0:服务账号身份验证
  • 1:用户账号身份验证
  • 2:预生成的刷新令牌或访问令牌身份验证
  • 3:应用默认凭据身份验证
  • 4:其他身份验证方法
-1 整数
PartnerToken 供 Google Cloud 合作伙伴用于跟踪驱动程序使用情况的令牌。 不适用 字符串
ProjectId 驱动程序的默认项目 ID。此项目用于执行查询,并按资源使用情况付费。如果未设置,驱动程序会推断项目 ID。 不适用 字符串 否,但强烈建议使用
ProxyHost 代理服务器的主机名或 IP 地址,JDBC 连接通过该代理服务器进行路由。 不适用 字符串
ProxyPort 代理服务器侦听连接的端口号。 不适用 字符串
ProxyPwd 通过需要进行身份验证的代理服务器连接时,用于身份验证的密码。 不适用 字符串
ProxyUid 通过需要进行身份验证的代理服务器连接时,用于身份验证的用户名。 不适用 字符串
QueryDialect 用于执行查询的 SQL 方言。使用 SQL 表示 GoogleSQL(强烈推荐),使用 BIG_QUERY 表示旧版 SQL。 SQL 字符串
QueryProperties 用于自定义查询行为的 REST 连接属性 不适用 Map<String, String>
RequestGoogleDriveScope 设置为 1 时,向连接添加只读的云端硬盘范围。 0 整数
RetryInitialDelay 设置第一次重试之前的延迟时间(以秒为单位)。 0
RetryMaxDelay 设置重试延迟时间上限(以秒为单位)。 0
ServiceAccountImpersonationChain 模拟链中以英文逗号分隔的服务账号电子邮件地址列表。 不适用 字符串
ServiceAccountImpersonationEmail 要模拟的服务账号电子邮件地址。 不适用 字符串
ServiceAccountImpersonationScopes 要与模拟账号搭配使用的 OAuth2 范围的逗号分隔列表。 https://www.googleapis.com/auth/bigquery 字符串
ServiceAccountImpersonationTokenLifetime 被模拟账号的令牌生命周期(以秒为单位)。 3600 整数
SSLTrustStore 包含受信任的证书授权机构 (CA) 证书的 Java TrustStore 的完整路径。驱动程序会利用此信任库在 SSL/TLS 握手期间验证服务器的身份。 不适用 字符串
SSLTrustStorePwd SSLTrustStore 属性中指定的 Java TrustStore 的密码。 不适用 字符串 仅当 Java TrustStore 受密码保护时
SWA_ActivationRowCount 阈值为 executeBatch insert 行,当超过此阈值时,连接器会切换到 Storage Write API。 3 整数
SWA_AppendRowCount 写入流的大小。 1000 整数
Timeout 连接器在超时之前重试失败的 API 调用的时长(以秒为单位)。 0
UniverseDomain 与贵组织的 Google Cloud 资源相关联的顶级网域。 googleapis.com 字符串
UnsupportedHTAPIFallback 确定连接器是回退到 REST API(设置为 TRUE 时)还是返回错误(设置为 FALSE 时)。 TRUE 布尔值
UseQueryCache 启用查询缓存。 TRUE 布尔值

使用驱动程序运行查询

通过 JDBC 驱动程序将 Java 应用连接到 BigQuery 后,您现在可以通过标准 JDBC 流程在开发环境中运行查询。您必须遵循所有 BigQuery 配额和限制

数据类型映射

通过适用于 BigQuery 的 JDBC 驱动程序运行查询时,会发生以下数据类型映射:

GoogleSQL 类型 Java 类型
ARRAY Array
BIGNUMERIC BigDecimal
BOOL Boolean
BYTES byte[]
DATE Date
DATETIME String
FLOAT64 Double
GEOGRAPHY String
INT64 Long
INTERVAL String
JSON String
NUMERIC BigDecimal
STRING String
STRUCT Struct
TIME Time
TIMESTAMP Timestamp

示例

以下部分提供了通过适用于 BigQuery 的 JDBC 驱动程序使用 BigQuery 功能的示例。

定位参数

以下示例运行了一个包含位置参数的查询:

PreparedStatement preparedStatement = connection.prepareStatement(
    "SELECT * FROM MyTestTable where testColumn = ?");
preparedStatement.setString(1, "string2");
ResultSet resultSet = statement.executeQuery(selectQuery);

嵌套和重复记录

以下示例查询了 Struct 数据的基础记录:

ResultSet resultSet = statement.executeQuery("SELECT STRUCT(\"Adam\" as name, 5 as age)");
    resultSet.next();
    Struct obj = (Struct) resultSet.getObject(1);
    System.out.println(obj.toString());

驱动程序以结构体对象或 JSON 对象的字符串表示形式返回基本记录。结果类似于以下内容:

{
  "v": {
    "f": [
      {
        "v": "Adam"
      },
      {
        "v": "5"
      }
    ]
  }
}

以下示例查询了 Struct 对象的子组件:

ResultSet resultSet = statement.executeQuery("SELECT STRUCT(\"Adam\" as name, 5 as age)");
    resultSet.next();
    Struct structObject = (Struct) resultSet.getObject(1);
    Object[] structComponents = structObject.getAttributes();
    for (Object component : structComponents){
      System.out.println(component.toString());
    }

以下示例查询了重复数据的标准数组,然后验证了结果:

// Execute Query
ResultSet resultSet = statement.executeQuery("SELECT [1,2,3]");
resultSet.next();
Object[] arrayObject = (Object[]) resultSet.getArray(1).getArray();

// Verify Result
int count =0;
for (; count < arrayObject.length; count++) {
  System.out.println(arrayObject[count]);
}

以下示例查询了重复数据的 Struct 数组,然后验证了结果:

// Execute Query
ResultSet resultSet = statement.executeQuery("SELECT "
    + "[STRUCT(\"Adam\" as name, 12 as age), "
    + "STRUCT(\"Lily\" as name, 17 as age)]");

Struct[] arrayObject = (Struct[]) resultSet.getArray(1).getArray();

// Verify Result
for (int count =0; count < arrayObject.length; count++) {
  System.out.println(arrayObject[count]);
}

批量插入

以下示例使用 executeBatch 方法执行批量插入操作。

Connection conn = DriverManager.getConnection(connectionUrl);
PreparedStatement statement = null;
Statement st = conn.createStatement();
final String insertQuery = String.format(
        "INSERT INTO `%s.%s.%s` "
      + " (StringField, IntegerField, BooleanField) VALUES(?, ?, ?);",
        DEFAULT_CATALOG, DATASET, TABLE_NAME);

statement = conn.prepareStatement(insertQuery1);

for (int i=0; i<2000; ++i) {
      statement.setString(1, i+"StringField");
      statement.setInt(2, i);
      statement.setBoolean(3, true);
      statement.addBatch();
}

statement.executeBatch();

价格

您可以免费下载适用于 BigQuery 的 JDBC 驱动程序,并且无需任何其他许可即可使用这些驱动程序。不过,当您使用该驱动程序时,需要按标准 BigQuery 价格付费。

后续步骤