通过JDBC直连使用SQL查询

更新时间:
复制为 MD 格式

表格存储提供 JDBC 驱动(com.aliyun.openservices:tablestore-jdbc),支持通过标准 JDBC 接口直连表格存储实例执行 SQL 查询。

前提条件

  • 已获取 AccessKey,RAM 用户需具备 "Action": "ots:SQL*" 权限。

  • 已创建数据表和映射表,详见DDL 操作

步骤一:安装 JDBC 驱动

可通过以下两种方式安装 JDBC 驱动。

添加Maven依赖

在 Maven 工程的 pom.xml 中添加表格存储 JDBC 驱动依赖。以 5.17.0 版本为例,在 <dependencies> 内加入如下内容:

<dependency>
  <groupId>com.aliyun.openservices</groupId>
  <artifactId>tablestore-jdbc</artifactId>
  <version>5.17.0</version>
</dependency>

手动安装

下载 表格存储 JDBC 驱动并导入到项目中。

步骤二:使用 JDBC 直连

  1. 使用 Class.forName() 加载表格存储 JDBC 驱动。

    表格存储 JDBC 驱动名称为 com.alicloud.openservices.tablestore.jdbc.OTSDriver

    Class.forName("com.alicloud.openservices.tablestore.jdbc.OTSDriver");
  2. 使用 JDBC 连接表格存储实例。

    String url = "jdbc:ots:https://myinstance.cn-hangzhou.ots.aliyuncs.com/myinstance";
    String user = "************************";
    String password = "********************************";
    Connection conn = DriverManager.getConnection(url, user, password);

    参数说明如下。

    参数

    说明

    url

    表格存储JDBCURL。格式为jdbc:ots:schema://[accessKeyId:accessKeySecret@]endpoint/instanceName[?param1=value1&...&paramN=valueN]。主要字段说明如下:

    • schema(必选):表格存储JDBC驱动使用的协议,一般设置为https。

    • accessKeyId:accessKeySecret(可选):阿里云账号或者RAM用户的AccessKey IDAccessKey Secret。

    • endpoint(必选):实例的服务地址。

    • instanceName(必选):实例名称。

    其他常用配置项的说明详见配置项

    user

    阿里云账号或者RAM用户的AccessKey ID。

    password

    阿里云账号或者RAM用户的AccessKey Secret。

    可通过 URL 或 Properties 方式传递 AccessKey 和配置项。以下以通过公网访问华东1(杭州)地域下 myinstance 实例为例。

    通过URL

    DriverManager.getConnection("jdbc:ots:https://************************:********************************@myinstance.cn-hangzhou.ots.aliyuncs.com/myinstance?enableRequestCompression=true");

    通过Properties

    Properties info = new Properties();
    info.setProperty("user", "************************");
    info.setProperty("password", "********************************");
    info.setProperty("enableRequestCompression", "true");
    DriverManager.getConnection("jdbc:ots:https://myinstance.cn-hangzhou.ots.aliyuncs.com/myinstance", info);
  3. 执行 SQL 语句。

    支持 createStatement 和 prepareStatement 两种方式。

    createStatement

    String sql = "SELECT pk1, col_a FROM test_table";
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
    while (rs.next()) {
        System.out.println(rs.getString("pk1") + ", " + rs.getLong("col_a"));
    }
    rs.close();
    stmt.close();

    prepareStatement

    String sql = "SELECT * FROM test_table WHERE pk = ?";
    PreparedStatement stmt = conn.prepareStatement(sql);
    stmt.setLong(1, 1);
    ResultSet rs = stmt.executeQuery();
    ResultSetMetaData meta = rs.getMetaData();
    while (rs.next()) {
        for (int i = 1; i <= meta.getColumnCount(); i++) {
            System.out.println(meta.getColumnName(i) + " = " + rs.getString(i));
        }
    }
    rs.close();
    stmt.close();

完整示例

以下示例用于查询表格存储实例中 test_table 的数据。

public class Demo {
    public static void main(String[] args) throws Exception {
        Class.forName("com.alicloud.openservices.tablestore.jdbc.OTSDriver");

        String url = "jdbc:ots:https://myinstance.cn-hangzhou.ots.aliyuncs.com/myinstance";
        String user = "************************";
        String password = "********************************";
        Connection conn = DriverManager.getConnection(url, user, password);

        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM test_table");
        ResultSetMetaData meta = rs.getMetaData();
        int colCount = meta.getColumnCount();
        while (rs.next()) {
            for (int i = 1; i <= colCount; i++) {
                System.out.print(meta.getColumnName(i) + "=" + rs.getString(i) + "\t");
            }
            System.out.println();
        }

        rs.close();
        stmt.close();
        conn.close();
    }
}

配置项

表格存储 JDBC 驱动基于 Java SDK 实现,支持通过 URL 参数或 Properties 修改配置项。

重要

SQL 请求服务端超时为 30 秒。如需更短的超时时间,将 syncClientWaitFutureTimeoutInMillis 设置为小于 30000 的值,或对每个 Statement 调用 setQueryTimeout 方法。

配置项

默认值

说明

enableRequestCompression

false

是否压缩请求数据。

enableResponseCompression

false

是否压缩响应数据。

ioThreadCount

2

HttpAsyncClient 的 IOReactor 线程数。

maxConnections

300

允许打开的最大 HTTP 连接数。

socketTimeoutInMillisecond

30000

Socket 层传输数据的超时时间。单位为毫秒。0 表示无限等待。

connectionTimeoutInMillisecond

30000

建立连接的超时时间。单位为毫秒。0 表示无限等待。

retryThreadCount

1

错误重试线程池的线程数。

syncClientWaitFutureTimeoutInMillis

-1

异步等待的超时时间。单位为毫秒。

connectionRequestTimeoutInMillisecond

60000

发送请求的超时时间。单位为毫秒。

retryStrategy

default

重试策略,取值范围如下:

  • disable:不重试。

  • default:重试 OTSNotEnoughCapacityUnitOTSTableNotReadyOTSPartitionUnavailableOTSServerBusyOTSQuotaExhaustedOTSTimeoutOTSInternalServerErrorOTSServerUnavailable 错误直到超时。

retryTimeout

10

重试超时时间和时间单位。时间单位的取值范围如下:

  • 秒:seconds

  • 毫秒:milliseconds

  • 微秒:microseconds

  • 纳秒:nanoseconds

  • 分钟:minutes

  • 小时:hours

retryTimeoutUnit

seconds

数据类型转换

表格存储支持 Integer、Double、String、Binary 和 Boolean 五种数据类型。JDBC 驱动在 Java 类型和表格存储数据类型之间自动转换。

Java类型转换为表格存储数据类型

使用 PreparedStatement 为 SQL 参数赋值时,支持 Byte、Short、Int、Long、BigDecimal、Float、Double、String、CharacterStream、Bytes、Boolean 类型。

PreparedStatement stmt = conn.prepareStatement("SELECT * FROM t WHERE pk = ?");
stmt.setLong(1, 1);                                // 支持
stmt.setURL(1, new URL("https://aliyun.com/"));    // 不支持,抛出异常

表格存储数据类型转换为Java类型

使用 ResultSet 获取返回结果时,数据类型自动转换规则如下。

表格存储数据类型

转换原则说明

Integer

  • 转为整型时,值超出范围则抛出异常。

  • 转为浮点数时,可能丢失精度。

  • 转为字符串或二进制时,等效于 toString()。

  • 转为布尔值时,非 0 值为 true。

Double

String

  • 转为整型或浮点数时,解析失败则抛出异常。

  • 转为布尔值时,字符串为 "true" 则结果为 true。

Binary

Boolean

  • 转为整型或浮点数时,true 为 1,false 为 0。

  • 转为字符串或二进制时,等效于 toString()。

Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT count(*) FROM t");
while (rs.next()) {
    rs.getLong(1);               // 支持
    rs.getCharacterStream(1);    // 不支持,抛出异常
}

表格存储数据类型和 Java 类型的转换支持情况如下。

说明

"✓"表示正常转换,"~"表示可能抛出异常,"×"表示无法转换。

类型转换

Integer

Double

String

Binary

Boolean

Byte

Short

Int

Long

BigDecimal

Float

Double

String

CharacterStream

×

×

×

Bytes

Boolean