JDBC
综述
鸿鹄实现了对JDBC的支持,可通过JDBC的接口或者第三方JDBC的客户端与之连接并发送SQL语句进行数据查询。
JDBC URL
jdbc:arrow-flight://<honghu_host>:<honghu_port>?useEncryption=0&token=<auth_token>
<honghu_host>对应鸿鹄服务所在的主机名称或 ip 地址<honghu_port对应honghu.vars中stonewave.rpc_port的值<auth_token>对应honghu.vars中global.server_token的值
caution
- 目前的JDBC链接不支持 SSL/TLS 加密
 - 目前的校验方式仅支持 auth token,用户名/密码 的方式并不支持
 
JDBC Driver
下载地址: https://central.sonatype.com/artifact/org.apache.arrow/flight-sql-jdbc-driver
JDK 版本要求
建议使用 JDK 版本 openjdk 13.0.2
对于JDK 9+的版本,需要添加如下JVM参数:
--add-opens=java.base/java.nio=ALL-UNNAMED
示例程序
package com.yanhuangdata;
import java.sql.Driver;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import org.apache.arrow.driver.jdbc.ArrowFlightJdbcDriver;
public class Main {
    // JDBC连接信息,替换对应的值
    static final String JDBC_URL = "jdbc:arrow-flight://<honghu_host>:<honghu_port>";
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        // 目前仅支持token的校验
        Properties properties = new Properties();
        properties.put("UseEncryptIon", "false");
        properties.put("token", "<auth_token>");
        try {
            // 1. 加载JDBC驱动
            final Driver driver = new ArrowFlightJdbcDriver();
            // 2. 建立数据库连接
            connection = driver.connect(JDBC_URL, properties);
            // 3. 编写SQL语句
            String sql = "SELECT * FROM main";
            // 4. 创建PreparedStatement对象
            preparedStatement = connection.prepareStatement(sql);
            // 5. 执行查询
            resultSet = preparedStatement.executeQuery();
            // 6. 处理元数据
            int columnCount = resultSet.getMetaData().getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                System.out.println("Column: " + resultSet.getMetaData().getColumnName(i));
            }
            // 7. 处理结果集
            while (resultSet.next()) {
                // 通过列名或索引获取数据
                String message = resultSet.getString("_message");
                // 在这里处理获取到的数据
                System.out.println("_message: " + message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 8. 关闭资源
            try {
                if (resultSet != null) resultSet.close();
                if (preparedStatement != null) preparedStatement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
对应的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yanhuangdata</groupId>
    <artifactId>jdbc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.arrow</groupId>
            <artifactId>flight-sql-jdbc-driver</artifactId>
            <version>14.0.2</version>
        </dependency>
    </dependencies>
</project>
上述示例程序中使用的
flight-sql-jdbc-driver是14.0.2的版本。
FAQ
1. 出现错误如何调试?
可以查看具体的错误信息,例如如果查询一个在鸿鹄中不存在的数据集foo_bar,则会有类似如下的错误信息:
Caused by: cfjd.org.apache.arrow.flight.FlightRuntimeException: UNKNOWN: Failed to create search job for query from flight sql client, sid: 192573d9-1d61-4cf8-80fc-7d1ea4136613, query: SELECT * FROM foo_bar, error: No such data set: foo_bar