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));
        }
    }
}

 

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