JDBC 连接器

DolphinDB 提供 JDBC 接口的连接器,可以让支持 JDBC 接口的客户端程序直接接入 DolphinDB。DolphinDB 的 JDBC 接口基于 DolphinDB Java API 的包实现。

注意:自 3.00.0.0 版本起,JDBC 支持 Catalog(目录)功能。本文“Catalog 功能”小节将进行详细说明。

JDBC 主要通过 JDBCStatement, JDBCPrepareStatementJDBCCallableStatement 三种接口提供诸多功能。

接口介绍
JDBCStatement可以正常访问数据库,适用于运行静态 SQL 语句。 Statement 接口不接受参数。
JDBCPrepareStatement继承了 JDBCStatement。可多次使用 SQL 语句, PreparedStatement 接口运行时接受输入的参数。
JDBCCallableStatement继承了 JDBCPrepareStatement。支持通过分号(;)分隔多个 SQL 语句,执行时不使用存储过程。

下面通过几个示例程序来展示以上三个对象的使用方法。

使用前,可以通过 maven 引入 JDBC:以 3.00.2.0 版本为例:

<dependency>
    <groupId>com.dolphindb</groupId>
    <artifactId>jdbc</artifactId>
    <version>3.00.2.0</version>
</dependency>

连接 DolphinDB

在支持 JDBC 连接的应用中,需要配置如下 JDBC 信息:

  • Driver Class Name: 驱动名称 DolphinDB JDBC 驱动名称是: com.dolphindb.jdbc.Driver

  • url: 连接字符串 连接字符串提供连接数据库的一些关键信息。一个 DolphinDB JDBC url 示例如下:

    jdbc:dolphindb://localhost:8848?user=admin&password=123456

    url 支持的参数如下:

    参数作用
    user数据库用户名。用于连接数据库。
    password用户密码。用于连接数据库。
    waitingTime测试连接的超时时间,单位为秒,默认值为 3。
    initialScript传入函数定义脚本。
    allowMultiQueries是否支持多条语句查询。布尔类型,默认为 false。在一条语句中,允许使用“;”来分隔多条查询。
    databasePath分布式数据库路径。指定该参数可以在初始化时将分布式表加载到内存。
    tableName分布式表的表名。指定该参数可以加载指定的分布式表。
    enableHighAvailability 或 highAvailability高可用参数,布尔类型,默认为 false。指定该参数可以开启或关闭高可用模式。注意事项及示例见下方说明。
    highAvailabilitySites字符串类型,表示开启高可用情况下指定填入的主机名和端口号数组,可选参数,默认值为 null。注意事项及示例见下方说明。
    sqlStd枚举类型,用于指定传入 SQL 脚本的解析语法。支持三种解析语法:DolphinDB、Oracle、MySQL,其中默认为 DolphinDB 解析。注意事项及示例见下方说明。
    tableAlias数据库表别名,用于在建立连接时传入一个或多个别名与数据库的组合。用户可通过别名访问数据库表。注意事项及示例见下方说明。
    reconnect布尔类型,表示是否开启单节点断连后自动重连,可选参数,默认值为 false,表示关闭。注意事项见下方说明。
    enableLoadBalance布尔类型,支持开启或关闭高可用模式下的负载均衡功能。注意事项及示例见下方说明。

    • 自1.30.21.1版本起,JDBC 支持高可用参数 enableHighAvailability,其作用与 highAvailability 相同。使用时只需设置其中一个参数即可(推荐使用 enableHighAvailability),若配置冲突则会报错。

    • 若需要创建 JDBCCallableStatement 对象,则连接字符串须指定 allowMultiQueries=true

    • 自1.30.22.1版本起,JDBC 支持参数 sqlStd 。用户可通过 url 直接传参,见示例1;也可通过 JDBCConnection 构造方法的 Properties 进行传参,见示例2。注意:须使用2.00.10版本以上的 DolphinDB。

    • DolphinDB server 自 2.00.15 版本起,新增 enableClientAuth 参数(默认为 false)用于验证连接用户的身份。当该参数配置为 true 时,通过 JDBC 连接 server 时的访客(guest)用户将只能执行认证与配置相关函数,包括通过 connect 方法传递的 initialScript 初始化脚本和 JDBC 在连接时执行初始化脚本。

      示例1

      通过 url 直接传参。

      Properties prop = new Properties();
      prop.setProperty("user","admin");
       prop.setProperty("password","123456");
      String url = "jdbc:dolphindb://" + HOST + ":" + PORT + "sqlStd:" + SqlStdEnum.MySQL.getName();
      conn = new JDBCConnection(url,prop);

      示例2

      JDBCConnection 构造方法的 Properties 参数支持 sqlStd 属性。用户通过 Properties 设置属性 key 为 sqlStd,值为字符串,即用户通过 SqlStdEnum 指定传入 SQL 脚本的解析语法。使用示例如下:

       Properties prop = new Properties();
       prop.setProperty("user","admin");
      prop.setProperty("password","123456");
      prop.setProperty("sqlStd", SqlStdEnum.DolphinDB.getName());
      String url = "jdbc:dolphindb://"+JDBCTestUtil.HOST+":"+JDBCTestUtil.PORT;
       conn = new JDBCConnection(url,prop);
  • 自1.30.22.2版本起,JDBC 支持参数 tableAlias。用户可通过 url 直接传参,见示例3-示例5;也可通过 JDBCConnection 构造方法的 Properties 进行传参,见示例6。

    示例3 DFS 表使用别名

    1. 使用默认别名。下例中以表名 pt 做为别名。

      tableAlias=dfs://valuedb/pt
    2. 指定别名。别名写在开头,别名与库表路径之间用冒号连接。下例中表的别名为 ttt

      tableAlias=ttt:dfs://valuedb/pt
    3. 同时设置多个库表的别名。值与值之间通过逗号“,”进行分隔。

      tableAlias=t1:dfs://valuedb/pt,dfs://valuedb/dt,dfs://valuedb/Order_tmp,dfs://testValue/nt

    示例4 MVCC 表使用别名

    使用默认别名。下例中以 MVCC 表的名字 mvcc13 做为别名。

    tableAlias=mvcc://work_dir/mvcc13

    指定别名。下例中以 mvcc13 做为别名。

    tableAlias=mvcc3:mvcc://work_dir/mvcc13

    linux server 中使用绝对路径指定别名。下例中使用 “/// ”表示绝对路径,表的别名为 mvcc2

    tableAlias=mvcc2:mvcc:///home/username/Adolphindb/2.00.6/server/work_dir/mvcc12;

    linux server 中使用相对路径指定别名。下例中使用“//” 表示相对路径,表的别名为 mvcc3

    tableAlias=mvcc3:mvcc://work_dir/mvcc13

    windows server 中指定别名。下例中表的别名为 mvcc14

    tableAlias=mvcc14:mvcc://C://DolphinDB/Data1/db12/mvcc14
    
    tableAlias=mvcc14:mvcc://C:\\DolphinDB\\Data1\\db12\\mvcc14;

    示例5 共享内存表使用别名

    指定别名。下例中以 tb8 做为表的别名。

    tableAlias=tb8:memTb2

    示例6 通过 Properties 指定别名

    下例中指定表的别名为 t1

    Properties info = new Properties();
    info.put("tableAlias","t1:dfs://valuedb/pt");
  • 自1.30.22.2版本起,JDBC 的高可用参数 highAvailabilitySites 支持通过逗号“,”分隔输入值。

    示例7 多个值之间通过逗号“,”分割(推荐写法)

    highAvailabilitySites=192.168.1.111:8841,192.168.1.111:8842,192.168.1.111:8843,192.168.1.111:8844

    示例8 多个值之间通过空格分割(不推荐)

    highAvailabilitySites=192.168.1.111:8841 192.168.1.111:8842 192.168.1.111:8843 192.168.1.111:8844
  • 自 2.00.11.0 版本起,JDBC 连接提供配置参数 enableLoadBalance

  • 自 3.00.2.0 版本起,JDBC 连接提供配置参数 reconnect。注意:开启高可用后,即设置 enableHighAvailability 为 true 时,reconnect 会默认始终为 true,此时对 reconnect 的配置无效。在关闭高可用后才可以任意配置 reconnect 的值。

高可用与负载均衡

JDBC 提供高可用模式与负载均衡功能,用户可通过相关参数进行配置。

版本号说明:1.30.22.5 为 JDBC 在 130 系列的最后一个版本,130 系列后即为 200 系列,2.00.11.0 为 JDBC 在 200 系列的第一个版本。

在 130 系列版本中,JDBC 开启高可用后即自动开启负载均衡。其中高可用与负载均衡的处理逻辑如下:

  • 若使用 1.30.22.2 之前的版本,JDBC 将选择最低负载节点进行连接;用户也可通过 highAvailabilitySites 指定可连接的节点组,此时 JDBC 将从 highAvailabilitySites 中随机进行连接。示例如下:

    public void test_enableHighAvailability() throws SQLException {
    	    String SITES = "192.168.0.69:18921 192.168.1.167:18922 192.168.0.69:18923 192.168.0.69:18924";
    	    String url = "jdbc:dolphindb://" + HOST + ":" + PORT + "?user=admin&password=123456&enableHighAvailability=true&highAvailabilitySites=" + SITES;
    	    Connection connection = DriverManager.getConnection(url);
    }
  • 在 1.30.22.2 版本中,JDBC 新增“低负载节点”概念(判断标准为:内存占用小于80%、连接数小于90% 且节点负载小于80%)。

  • 若使用 1.30.22.2 及之后的版本,开启高可用后,JDBC 将优先随机选择一个低负载节点进行连接,若没有低负载节点,则将随机连接一个可用节点。若用户通过 highAvailabilitySites 指定了可连接的节点组,此时 JDBC 将仍优先从 highAvailabilitySites 中随机连接一个低负载节点,若无,则随机选择一个 highAvailabilitySites 中的可用节点。

在 200 系列版本中,从 2.00.11.0 起,JDBC 支持将高可用与负载均衡进行逻辑分离。用户可以通过 url 或 prop 属性设置配置参数 enableLoadBalance,以关闭或开启高可用模式下的负载均衡。详细逻辑如下:

  • 若仅开启高可用,不填写 enableLoadBalance,则为了兼容先前版本,此时将遵循 1.30.22.2 及之后的 130 系列版本的描述逻辑。

  • 若同时开启高可用和负载均衡(enableLoadBalance = true),遵循 1.30.22.2 及之后的 130 系列版本的描述逻辑。

  • 若开启高可用,不开启负载均衡功能(enableLoadBalance = false),则将连接 url 中HOSTPORT 组成的节点或 Properties 中 hostName, localhostport 组成的节点。

    // 开启高可用、不开启负载均衡使用示例
    public void test_enableHighAvailability_and_enableLoadBalance() throws SQLException {
    	    String SITES = "192.168.0.69:18921 192.168.1.167:18922 192.168.0.69:18923 192.168.0.69:18924";
    	    String url = "jdbc:dolphindb://" + HOST + ":" + PORT + "?user=admin&password=123456&enableHighAvailability=true&highAvailabilitySites=" + SITES + "&enableLoadBalance=false";
    	    Connection connection = DriverManager.getConnection(url);
    }
  • 注意:不支持仅开启负载均衡的情况。

Catalog 功能

自 3.00.0.0 版本起,JDBC 支持 Catalog(目录)功能。即支持如 select * from catalog.schema.table 或者 select * from schema.table 的查询方式。以下将介绍现支持的 Catalog 的相关方法。

注意:

  • 使用完整的 Catalog 功能需同时使用 3.00.0.0 及以上版本的 DolphinDB Server 和 JDBC(建议版本号前三段一致)。否则相关接口将不支持或返回 null。

  • 自 JDBC 3.00.4.0 起,也可连接 2.00.0.0 及以上版本的 DolphinDB Server,但仅提供名为 "DolphinDB"的虚拟 Catalog,用于兼容,不支持多 Catalog。其中,分布式数据库名映射为 Schema,分布式表名映射为 Table。

方法功能
getCatalogs获取数据库中所有可用的 catalog 名称
getTables获取指定 catalog、schema 下表的相关信息
getColumns获取指定 catalog、schema、table 下列的相关信息
getSchemas获取指定 catalog 下所有的 schema
setCatalog设置当前 catalog 名称
getCatalog获取当前 JDBCConnection 中设置的 catalog 名称

其中:

  • getCatalogs, getTables, getColumns, getSchemasJDBCDataBaseMetaData 提供的方法。
  • setCatalog, getCatalogJDBCConnection 提供的方法。

以下对各个方法的使用进行详细说明:

getCatalogs

getCatalogs()

获取数据库中所有可用的 catalog 名称。无参数。

示例

Connection conn = DriverManager.getConnection(url);
DatabaseMetaData metaData = conn.getMetaData();
ResultSet rs = metaData.getCatalogs();

getTables

getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)

获取指定 catalog、schema 下表的相关信息。

参数介绍

  • catalog:可选参数,字符串,用于指定表所属的 catalog。
  • schemaPattern:可选参数,字符串,用于指定表所属的模式。
  • tableNamePattern:必填参数,字符串,用于指定要匹配的表名的模式。
  • types:可选参数,字符串数组,用于指定要返回哪些类型的表。注意,DolphinDB 只支持返回 TABLE 类型,因此该字段只能填 “null“ 或者 “TABLE“。

使用说明

目前仅支持如下三种用法:

  1. 传入具体的 catalogschema, tableName 均为“%”。表示获取该 catalog 下的所有表。
  2. 传入具体的 catalog, schematableName 为“%”。表示获取该 schema 下的所有 tables。
  3. catalog, schema 均为 “null“,tableName 为“%”。表示获取所有内存表。

返回值说明

将返回一个表,如下为列属性介绍:

  • TABLE_CAT:表所属的 catalog 名称。dfs 表将返回对应的值;内存表则返回为空。
  • TABLE_NAME:表的名称。
  • TABLE_SCHEM:表所属的 schema 名称。
  • TABLE_TYPE:表的类型,通常是 "TABLE"。
  • REMARKS:表的描述或备注信息,通常为 null。

示例

1 获取指定的 catalog下的所有表相关信息:

// 获取 "catalog1" 下的所有表信息
ResultSet rs = metaData.getTables("catalog1","%","%", null);

2 获取指定的 catalog、schema 下的所有表相关信息:

// 获取 "catalog1.schema_test" 下的所有表相关信息
ResultSet rs = metaData.getTables("catalog1","schema_test","%", null);

3 获取所有内存表相关信息:

ResultSet rs = metaData.getTables(null,null,"%", null);

getColumns

getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) 

获取指定 catalog、schema、table 中列的相关信息。

参数介绍

  • catalog:可选参数,字符串,用于指定表所属的 catalog。
  • schemaPattern:可选参数,字符串,用于指定表所属的模式。
  • tableNamePattern:必填参数,字符串,用于指定要匹配的表名的模式。
  • columnNamePattern:可选参数,字符串,用于指定要检索的列的名称模式。目前仅支持填为“%”。

使用说明

目前仅支持以下两种用法:

  1. 传入具体的 catalog, schema, table;columnName 为“%”。表示获取该表下的所有列。
  2. catalog, schema 为空;传入具体的 table,columnName 为“%”。表示获取内存表下的列信息。

返回值说明

将返回一个表,如下为列属性介绍:

  • COLUMN_NAME:列名。
  • TYPE_NAME:数据类型。
  • DATA_TYPE:值为 java.sql.Types。
  • EXTRA:暂不支持,返回为 null。
  • REMARKS:列信息,返回为 null。
  • ORDINAL_POSITION:列在表中的原始位置,从 1 开始。
  • IS_NULLABLE:使用 ISO 规则确定列可否包含空数据。只有分布式表的分区列返回 'NO'(不能为空),其他列都返回 'YES'(可以为空)。
  • SQL_DATA_TYPES: INT,取 java.sql.Types 的类型值。比如 DolphinDB 中的 STRING 类型对应 VARCHAR,即取 12; DATE 取 91;DECIMAL 32,DECIMAL 64,DECIMAL 128 都取 3。参考 JDBCResultSetMetaData.java Types 方法。

示例

1 获取 dfs 表的列相关信息

// 获取 catalog1.schema_test.dt 表的所有列相关信息
ResultSet rs = metaData.getColumns("catalog1","schema_test","dt", "%");

2 获取内存表的列相关信息

// 获取内存表 "table1"下的所有列相关信息
ResultSet rs = metaData.getColumns(null, null, "table1", "%");

getSchemas

用法一

getSchemas()

表示获取当前连接设置的 catalog 下的所有 schema 信息(设置操作参考 setCatalog)。无参数。

用法二

getSchemas(String catalog, String schemaPattern)

获取指定 catalog 下所有的 schema。

用法二参数介绍

  • catalog:字符串,表示 catalog 的名称。
  • schemaPattern:字符串,表示 schema 的名称。目前仅支持填为“%”。

用法二使用说明

只支持指定 catalog,schemaPattern填为“%”。表示获取指定 catalog 下的所有 schema。

两种用法的返回值说明

  • TABLE_SCHEM:表示 schema 名称。
  • TABLE_CATALOG:表示 catalog 名称。

示例:

1 获取当前连接所设定的 catalog 下的所有 schema:

ResultSet rs = metaData.getSchemas();

2 获取指定的 catalog 下的所有 schema 相关信息:

// 获取 "catalog1" 下的所有 schema 相关信息:
ResultSet rs = metaData.getSchemas("catalog1", "%");

getCatalog

getCatalog() 

获取当前 JDBCConnection 中设置的 catalog。无参数。

示例

Connection conn = DriverManager.getConnection(url);
String catalog = conn.getCatalog();

setCatalog

setCatalog(String catalog) 

设置当前 catalog 名称。

参数介绍

catalog:字符串,表示 catalog 的名称。

示例

设置当前 JDBCConnection 的 catalog。

// 设置当前 JDBCConnection 的 catalog 为 "catalog1"
Connection conn = DriverManager.getConnection(url);
String catalog = conn.setCatalog("catalog1");

内存表的增删改查

使用 Java API 将 demo 需要的模板表保存到磁盘。在 demo 中通过 loadTable 可以快速创建内存表。请注意,变量名及表名不可与 DolphinDB 的关键字同名。脚本代码如下:

public static boolean CreateTable(String database, String tableName, String host, int port) {
    boolean success = false;
    DBConnection db = null;
    try {
        String sb = "bool = [1b, 0b];\n" +
            "char = [97c,'A'];\n" +
            "short = [122h, 123h];\n" +
            "int = [21, 22];\n" +
            "long = [22l, 23l];\n" +
            "float  = [2.1f, 2.2f];\n" +
            "double = [2.1, 2.2];\n" +
            "string= [`Hello, `world];\n" +
            "date = [2013.06.13, 2013.06.14];\n" +
            "month = [2016.06M, 2016.07M];\n" +
            "time = [13:30:10.008, 13:30:10.009];\n" +
            "minute = [13:30m, 13:31m];\n" +
            "second = [13:30:10, 13:30:11];\n" +
            "datetime = [2012.06.13 13:30:10, 2012.06.13 13:30:10];\n" +
            "timestamp = [2012.06.13 13:30:10.008, 2012.06.13 13:30:10.009];\n" +
            "nanotime = [13:30:10.008007006, 13:30:10.008007007];\n" +
            "nanotimestamp = [2012.06.13 13:30:10.008007006, 2012.06.13 13:30:10.008007007];\n" +
            "tb1= table(bool,char,short,int,long,float,double,string,date,month,time,minute,second,datetime,timestamp,nanotime,nanotimestamp);\n" +
            "db=database(\"" + database + "\");\n" +
            "saveTable(db, tb1, `" + tableName + ");\n";
        db = new DBConnection();
        db.connect(host, port);
        db.run(sb);
        success = true;
    } catch (Exception e) {
        e.printStackTrace();
        success = false;
    } finally {
        if (db != null)
            db.close();
        return success;
    } 
}

内存表新增记录

通过 JDBC 接口对内存表的操作主要是通过 prepareStatement 预置 sql 模板,并通过 set 写入参数,最后通过 executeUpdate 函数填充参数并执行语句。

public static void InMemmoryAddTest(String database, String tableName) {
    try {
        Class.forName(JDBC_DRIVER);
        conn = DriverManager.getConnection(DB_URL_WITHLOGIN);

        JDBCStatement stm = (JDBCStatement) conn.createStatement();
        stm.execute("memTable = loadTable('" + database + "',\"" + tableName + "\")");
        // SQL insert 语句
        stmt = conn.prepareStatement("insert into memTable values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
        stmt.setBoolean(1, true);
        stmt.setByte(2, (byte) 98);
        stmt.setShort(3, (short) 112);
        stmt.setInt(4, 21);
        stmt.setLong(5, 22l);
        stmt.setFloat(6, 2.1f);
        stmt.setDouble(7, 2.1);
        stmt.setString(8, "hello");
        stmt.setDate(9, Date.valueOf(LocalDate.of(2013, 06, 13)));
        stmt.setObject(10, new BasicMonth(YearMonth.of(2016, 06)));
        stmt.setObject(11, Time.valueOf("13:30:10"));
        stmt.setObject(12, LocalTime.of(13, 30));
        stmt.setObject(13, LocalTime.of(13, 30, 10));
        stmt.setObject(14, LocalDateTime.of(2012, 06, 13, 13, 30, 10));
        stmt.setObject(15, LocalDateTime.of(2012, 06, 13, 13, 30, 10, 8000000));
        stmt.setObject(16, LocalTime.of(13, 30, 10, 8007006));
        stmt.setObject(17, LocalDateTime.of(2012, 06, 13, 13, 30, 10, 8007006));
        stmt.executeUpdate();

        // 加载数据库中的表格
        ResultSet rs = stmt.executeQuery("select * from memTable");
        printData(rs);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (stmt != null)
                stmt.close();
        } catch (SQLException se2) {
        }
        try {
            if (conn != null)
                conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        }
    }
}

删除内存表中数据

需要删除内存表中数据,需在以下脚本的 "?" 处填相应的的删除条件。

public static void InMemoryDeleteTest(String database, String tableName){
    try {
        Class.forName(JDBC_DRIVER);
        conn = DriverManager.getConnection(DB_URL_WITHLOGIN);
        JDBCStatement stm = (JDBCStatement)conn.createStatement();
        stm.execute("memTable = loadTable('" + database + "',\"" + tableName + "\")");
        // SQL delete 语句
        stmt = conn.prepareStatement("delete from memTable where char = ?");
        stmt.setByte(1, (byte)'A');
        stmt.executeUpdate();
        // 读取表格检查是否删除
        ResultSet rs = stmt.executeQuery("select * from memTable");
        System.out.println("==========InMemoryDeleteTest======================");
        printData(rs);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (stmt != null)
                stmt.close();
        } catch (SQLException se2) {
        }
        try {
            if (conn != null)
                conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        }
    }
}

内存表的更改

public static void InMemoryUpdateTest(String database, String tableName){
    try {
        Class.forName(JDBC_DRIVER);
        conn = DriverManager.getConnection(DB_URL_WITHLOGIN);
        JDBCStatement stm = (JDBCStatement)conn.createStatement();
        stm.execute("memTable = loadTable('" + database + "',\"" + tableName + "\")");
        // SQL update 语句
        stmt = conn.prepareStatement("update memTable set bool = 0b where char = 97c");
        stmt.executeUpdate();
        // 读取表格检查是否更新
        ResultSet rs = stmt.executeQuery("select * from memTable where char=97c");
        printData(rs);
    } catch (Exception e) {
        e.printStackTrace();
    } finally
    {
        try {
            if (stmt != null)
                stmt.close();
        } catch (SQLException se2) {
        }
        try {
            if (conn != null)
                conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        }
    }
}

分布式表的新增和查询

DolphinDB 支持分布式数据表。本例子演示通过 JDBC 来进行分布式表的新增和查询。要操作分布式表,连接的时候需在 URL 中加入 databasePathgetConnection() 时会预先加载分区表的元数据。

示例如下:

jdbc:dolphindb://localhost:8848?databasePath=dfs://valuedb

创建分区表

使用 Java API 执行创建分区表的语句,以创建示例所需的分区数据库。示例中使用了 VALUE 方式进行数据分区。需要了解其他分区方式,请点击 DolphinDB 数据库分区教程

public static boolean CreateValueTable(String database, String tableName, String host, String port) {
    boolean success = false;
    DBConnection db = null;
    StringBuilder sb = new StringBuilder();
    sb.append("login(\"admin\",\"123456\")\n");
    sb.append("n=3000\n");
    sb.append("month=take(2000.01M..2019.05M, n)\n");
    sb.append("x=take(1..1000, n)\n");
    sb.append("t=table(month, x)\n");
    sb.append("if(existsDatabase(\"" + database + "\"))\n" +
              "dropDatabase(\"" + database + "\")\n");
    sb.append("db=database(\"" + database + "\", VALUE, 2000.01M..2019.05M)\n");
    sb.append("pt = db.createPartitionedTable(t, `" + tableName + ", `month)\n");
    sb.append("pt.append!(t)\n");
    db = new DBConnection();
    try {
        db.connect(host, Integer.parseInt(port));
        db.run(sb.toString());
        success = true;
    } catch (NumberFormatException | IOException e) {
        e.printStackTrace();
        success = false;
    } finally {
        if (db != null)
            db.close();
        return success;
    }
}

分区表内容的增加和查询

public static void DFSAddTest(String database, String tableName) {
    try {
        Class.forName(JDBC_DRIVER);

        // dfs 下会预先 load table
        conn = DriverManager.getConnection(DB_URL_WITHLOGIN);
        JDBCStatement stm = (JDBCStatement) conn.createStatement();
        stm.execute("dfsTable = loadTable('" + database + "',\"" + tableName + "\")");
        // SQL insert 语句
        stmt = conn.prepareStatement("insert into dfsTable values(?,?)");
        stmt.setObject(1, new BasicMonth(YearMonth.of(2016, 06)));
        stmt.setInt(2, 3);
        stmt.executeUpdate();
        // 读取表格检查是否新增数据
        ResultSet rs = stmt.executeQuery("select count(*) from loadTable(\"" + database + "\", `"+ tableName +")");
        printData(rs);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (stmt != null)
                stmt.close();
        } catch (SQLException se2) {
        }
        try {
            if (conn != null)
                conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        }
    }
}

查询超时功能

自 3.00.2.0 版本起,JDBC 支持查询超时功能。查询超时是指数据库在执行查询操作时等待结果的最长时间。如果在这个时间内没有返回查询结果,JDBC 驱动程序将抛出 SQLTimeoutException 异常。设置查询超时可以有效避免长时间等待无响应的查询,从而避免线程阻塞和资源浪费。

设置方法 :在 JDBCStatementJDBCPreparedStatement 对象中,使用 setQueryTimeout(int seconds) 方法来设置查询超时时间(正数,以秒为单位)。例如:

Statement stmt = conn.createStatement();
stmt.setQueryTimeout(5); // 设置查询超时时间为5秒
ResultSet rs = stmt.executeQuery("SELECT * FROM my_table");

注意 :JDBC 会将 JDBCStatementJDBCPreparedStatement 类中关于运行时间的限制应用到其对应的 execute, executeQuery, executeUpdateexecuteBatch 方法。即当一个 JDBCStatementJDBCPreparedStatement 对象使用了 setQueryTimeout 方法设置了最大查询时间后,调用该对象的 execute, executeQuery, executeUpdateexecuteBatch 方法都会保持相同的超时设置。

参考及附录

  • 在 JDBC 接口中,可以使用 execute 方法执行所有的 DolphinDB SQL 语句,具体语法参考 DolphinDB SQL 语法
  • JDBC 中 executeUpdate(sql) 返回 SQL 语句更新的记录数,而在 DolphinDB JDBC 连接器中 executeUpdate(sql) 不支持返回 delete, update 和调用 append 的语句所影响的记录数。
  • 由于 DolphinDB 不支持更高精度的 BigDecimal 类型,故 DolphinDB JDBC 连接器将 BigDecimal 类型转换为 DOUBLE 类型。
  • 下载 示例所有代码。