MaxCompute JDBC使用说明和实例

MaxCompute JDBC

MaxCompute JDBC驱动是MaxCompute提供的Java数据库连接(Java Database Connectivity)接口,可以通过标准的JDBC编程基于MaxCompute执行海量数据的分布式计算查询。MaxCompute JDBC驱动还可以用于连接MaxCompute和支持JDBC的工具。使用说明文档见:MaxCompute JDBC概述

通过MaxCompute JDBC驱动执行SQL并获取结果,需要执行账号满足以下要求:

  • 是项目空间的成员。
  • 有项目空间中CreateInstance权限。
  • 有目标表的Select与Download权限。

第三方工具的使用具体见MaxCompute文档:

一些常见问题  

是否支持连接池与Auto-Commit?

MaxCompute本身提供Rest服务,和传统数据库维持长连接的方式十分不同。MaxCompute JDBC驱动创建Connection是十分轻量的操作,因此并无必要针对MaxCompute JDBC刻意使用连接池。当然,MaxCompute JDBC也支持使用连接池的场景。

由于MaxCompute不支持Transaction,每个查询动作都会即时体现到服务端,即默认为Auto-Commit的行为。因此MaxCompute JDBC驱动不支持关闭Auto-Commit模式。

如何获取MaxCompute Logview URL?

MaxCompute JDBC驱动是基于MaxCompute Java SDK的封装。因此,与MaxCompute客户端、MaxCompute Studio以及Dataworks一样,通过MaxCompute JDBC驱动执行SQL时,会生成Logview URL。您可以通过Logview查看任务执行状态,追踪任务进度,获取任务执行结果。Logview URL可以通过properties.log4j进行配置,默认打印到STDERR。

MaxCompute JDBC使用说明

JDBC Maven依赖

通过Maven方式使用MaxCompute JDBC的项目对象模型POM(Project Object Model)示例片段如下。

<dependency>
  <groupId>com.aliyun.odps</groupId>
  <artifactId>odps-jdbc</artifactId>
  <version>3.0.1</version>
  <classifier>jar-with-dependencies</classifier>
</dependency>

连接MaxCompute

1. 加载MaxCompute JDBC驱动:

Class.forName("com.aliyun.odps.jdbc.OdpsDriver");

2. 通过DriverManager创建Connection:

Connection cnct = DriverManager.getConnection(url, accessId, accessKey);

参数说明如下:

  • url:格式为jdbc:odps:<MaxCompute endpoint>?project=<MaxCompute project name>。 其中:举例如下。
    jdbc:odps:http://service.cn-hangzhou.maxcompute.aliyun.com/api?project=test_project
    • <maxcompute_endpoint>为自己MaxCompute服务所在区域的Endpoint。例如,华东1(杭州)区域的外网Endpoint为http://service.cn-hangzhou.maxcompute.aliyun.com/api。更多关于Endpoint的配置信息,请参见配置Endpoint
    • <maxcompute_project_name> 为自己的MaxCompute项目空间名称。
  • accessId:创建项目空间的AccessKey ID。
  • accessKey:创建项目空间的AccessKey ID对应的AccessKey Secret。

3. 执行查SQL语句:

Statement stmt = cnct.createStatement();
ResultSet rset = stmt.executeQuery("SELECT foo FROM bar");

while (rset.next()) {
    // process the results
}

rset.close();
stmt.close();
conn.close();

示例代码

1. 删除表,创建表,获取Metadata:

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {

    private static final String DRIVER_NAME = "com.aliyun.odps.jdbc.OdpsDriver";

    public static void main(String[] args) throws SQLException {
        try {
            Class.forName(DRIVER_NAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        }

        Connection conn = DriverManager.getConnection(
            "jdbc:odps:<maxcompute endpoint>?project=<maxcompute project>",
            "aliyun accessId", "aliyun accessKey");


        // create a table
        Statement stmt = conn.createStatement();
        final String tableName = "jdbc_test";
        stmt.execute("DROP TABLE IF EXISTS " + tableName);
        stmt.execute("CREATE TABLE " + tableName + " (key BIGINT, value STRING)");

        // get meta data
        DatabaseMetaData metaData = conn.getMetaData();
        System.out.println("product = " + metaData.getDatabaseProductName());
        System.out.println("jdbc version = "
            + metaData.getDriverMajorVersion() + ", "
            + metaData.getDriverMinorVersion());
        ResultSet tables = metaData.getTables(null, null, tableName, null);
        while (tables.next()) {
            String name = tables.getString("TABLE_NAME");
            System.out.println("inspecting table: " + name);
            ResultSet columns = metaData.getColumns(null, null, name, null);
            while (columns.next()) {
                System.out.println(
                    columns.getString("COLUMN_NAME") + "\t" +
                        columns.getString("TYPE_NAME") + "(" +
                        columns.getInt("DATA_TYPE") + ")");
            }
            columns.close();
        }

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

预期输出:

product = MaxCompute/ODPS
jdbc version = 3, 0
inspecting table: jdbc_test
key    BIGINT(-5)
value    STRING(12)

2. 执行INSERT:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {

    private static final String DRIVER_NAME = "com.aliyun.odps.jdbc.OdpsDriver";

    public static void main(String[] args) throws SQLException {
        try {
            Class.forName(DRIVER_NAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        }

        Connection conn = DriverManager.getConnection(
            "jdbc:odps:http://10.101.222.162:8002/odps_dailyrunnew?project=odps_mingyou_test",
            "63wd3dpztlmb5ocdkj94pxmm", "oRd30z7sV4hBX9aYtJgii5qnyhg=");

        Statement stmt = conn.createStatement();
        // The following DML also works
        //String dml = "INSERT INTO jdbc_test SELECT 1, \"foo\"";
        String dml = "INSERT INTO jdbc_test VALUES(1, \"foo\")";
        int ret = stmt.executeUpdate(dml);

        assert ret == 1;

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

3. 执行批量INSERT:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Main {

    private static final String DRIVER_NAME = "com.aliyun.odps.jdbc.OdpsDriver";

    public static void main(String[] args) throws SQLException {
        try {
            Class.forName(DRIVER_NAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        }

        Connection conn = DriverManager.getConnection(
            "jdbc:odps:<maxcompute endpoint>?project=<maxcompute project>",
            "aliyun accessId", "aliyun accessKey");

        PreparedStatement pstmt = conn.prepareStatement("INSERT INTO jdbc_test VALUES(?, ?)");

        pstmt.setLong(1, 1L);
        pstmt.setString(2, "foo");
        pstmt.addBatch();

        pstmt.setLong(1, 2L);
        pstmt.setString(2, "bar");
        pstmt.addBatch();

        int[] ret = pstmt.executeBatch();

        assert ret[0] == 1;
        assert ret[1] == 1;

        pstmt.close();
        conn.close();
    }
}

4. 执行SELECT:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {

    private static final String DRIVER_NAME = "com.aliyun.odps.jdbc.OdpsDriver";

    public static void main(String[] args) throws SQLException {
        try {
            Class.forName(DRIVER_NAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        }

        Connection conn = DriverManager.getConnection(
            "jdbc:odps:<maxcompute endpoint>?project=<maxcompute project>",
            "aliyun accessId", "aliyun accessKey");
        ResultSet rs;

        Statement stmt = conn.createStatement();
        String sql = "SELECT * FROM JDBC_TEST";
        stmt.executeQuery(sql);

        ResultSet rset = stmt.getResultSet();
        while (rset.next()) {
            System.out.println(String.valueOf(rset.getInt(1)) + "\t" + rset.getString(2));
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章