The MaxCompute JDBC driver lets you connect to MaxCompute from any Java application or BI tool that supports the JDBC standard. This topic covers how to download the driver, configure connection parameters, and run SQL queries.
Prerequisites
Before you begin, make sure you have:
-
Membership in a MaxCompute project
-
The CREATE INSTANCE permission on the project
-
The SELECT and DOWNLOAD permissions on the tables you want to query
Permission requirements vary by driver version:
V1.9 or earlier: Each query creates a temporary table; results are fetched via Tunnel commands. The CREATE TABLE permission is also required.
V2.2 or later: No temporary table is created. Query results are fetched directly via the InstanceTunnel interface. The CREATE TABLE permission is not required. For a full list of MaxCompute permissions, see MaxCompute permissions.
Usage notes
Data protection: If data protection is enabled for a project, data cannot be moved out of the project.
-
JDBC earlier than V2.4: No result sets can be retrieved.
-
JDBC V2.4 or later: The number of rows returned cannot exceed the value of the
READ_TABLE_MAX_ROWparameter.
For details, see Project operations and Project data protection.
V2.0 data types: To use the extended MaxCompute V2.0 data types (TINYINT, SMALLINT, DATETIME, TIMESTAMP, ARRAY, MAP, STRUCT), run the following command before executing queries:
set odps.sql.type.system.odps2=true
For more information, see Data type editions.
Download the driver
Download the MaxCompute JDBC driver JAR package from any of the following sources:
-
OSS (direct link): odps-jdbc-3.4.4-jar-with-dependencies.jar
-
GitHub: aliyun-odps-jdbc releases
-
Maven: Search for
a:odps-jdbcon Maven Central
Download the package whose filename includes jar-with-dependencies. This fat JAR bundles all required dependencies and avoids version conflicts at runtime.
Maven dependency (POM):
<dependency>
<groupId>com.aliyun.odps</groupId>
<artifactId>odps-jdbc</artifactId>
<version>3.8.6</version>
<classifier>jar-with-dependencies</classifier>
</dependency>
If you add the JDBC dependency above, do not add the MaxCompute SDK dependency separately. The JDBC JAR already includes the SDK. Adding both may cause version conflicts.
The MaxCompute JDBC driver is open source at aliyun/aliyun-odps-jdbc. Report bugs on the Issues tab and contribute code on the Pull requests tab, following the project's template requirements.
Connect to MaxCompute
All connections use the JDBC URL format below, with credentials passed as separate parameters.
Connection URL format:
jdbc:odps:<maxcompute_endpoint>?project=<maxcompute_project_name>[&useProjectTimeZone={true|false}]
Example:
jdbc:odps:http://service.cn-hangzhou.maxcompute.aliyun.com/api?project=test_project&useProjectTimeZone=true
Replace <maxcompute_endpoint> with the endpoint for your region. For example, the public endpoint for China (Hangzhou) is http://service.cn-hangzhou.maxcompute.aliyun.com/api. For all region endpoints, see Endpoints.
Property parameters take higher priority than URL parameters. If the URL contains odps_config=config_file, the file is read as a set of property parameters.
Connect and run a query:
// Step 1: Load the driver
Class.forName("com.aliyun.odps.jdbc.OdpsDriver");
// Step 2: Establish a connection
Connection cnct = DriverManager.getConnection(url, accessId, accessKey);
// Step 3: Execute a query
try (
Statement stmt = cnct.createStatement();
ResultSet rset = stmt.executeQuery("SELECT foo FROM bar;")
) {
while (rset.next()) {
// process the results
}
} catch (SQLException e) {
// handle the exception
} finally {
if (cnct != null) {
try {
cnct.close();
} catch (SQLException e) {
// ignore or log
}
}
}
For AccessKey ID and AccessKey secret setup, see Create an Alibaba Cloud account.
JDBC parameters
Configure the connection using URL parameters or a Java Properties object. Property parameters override URL parameters.
Basic parameters
| URL key | Property key | Required | Description |
|---|---|---|---|
project |
project_name |
Yes | The name of the MaxCompute project. |
accessId |
access_id |
Yes | Your AccessKey ID. Get it from the AccessKey Pair page. |
accessKey |
access_key |
Yes | Your AccessKey secret. Get it from the AccessKey Pair page. |
logview |
logview_host |
No | The URL of MaxCompute LogView. Set to http://logview.odps.aliyun.com. |
tunnelEndpoint |
tunnel_endpoint |
No | The endpoint of MaxCompute Tunnel. See Endpoints for values by region. |
Log configuration parameters
| URL key | Property key | Required | Description | Default |
|---|---|---|---|---|
enableOdpsLogger |
enable_odps_logger |
No | Enables the JDBC logger. When set to True, logs are written to jdbc.log in the directory where the JAR is stored. |
False |
logConfFile |
log_conf_file |
No | SLF4J (Simple Logging Facade for Java) configuration file for flexible log output (output file, log level, etc.). Requires logback dependencies in pom.xml: ch.qos.logback:logback-core:1.2.3 and ch.qos.logback:logback-classic:1.2.3. See the logback.xml example. |
— |
logLevel |
log_level |
No | The log level. | INFO |
Connection and timeout parameters
| URL key | Property key | Required | Description | Default |
|---|---|---|---|---|
connectTimeout |
connect_timeout |
No | Timeout for establishing the underlying network connection. Unit: seconds. | 10 |
readTimeout |
read_timeout |
No | Timeout for reading data over the connection. Unit: seconds. The total timeout per RESTful API request is connectTimeout + readTimeout (default: 130 seconds). Each request retries up to 3 times. To extend the request timeout, increase readTimeout. |
120 |
tunnelConnectTimeout |
tunnel_connect_timeout |
No | Timeout for the Tunnel connection when downloading data. Unit: seconds. | 180 |
tunnelReadTimeout |
tunnel_read_timeout |
No | Timeout for reading data via Tunnel. Unit: seconds. | 300 |
httpsCheck |
https_check |
No | Specifies whether to perform HTTPS certificate verification. | False |
Other parameters
| URL key | Property key | Required | Description | Default |
|---|---|---|---|---|
stsToken |
sts_token |
No | Alibaba Cloud Security Token Service (STS) token. | — |
charset |
charset |
No | Character set for input and output. | UTF-8 |
useProjectTimeZone |
use_project_time_zone |
No | Specifies whether to use the time zone set by the odps.sql.timezone parameter in the MaxCompute project. Priority order: statement-level setting > project-level setting > unspecified. You can also set the time zone per statement with set odps.sql.timezone=xxx. |
False |
disableConnectinosSetting |
disable_connection_setting |
No | Controls whether the set command in a statement also updates the connection-level SQL parameters. When set to True, running set configures both the statement and the connection. When set to False, set applies to the statement only. |
False |
settings |
settings |
No | Default global SQL settings in JSON format. Example: {"odps.sql.type.system.odps2": "true"}. |
— |
tableList |
table_list |
No | Tables to include, in the format projectname.tablename,projectname1.tablename1. Example: myproject.orders,myproject.users. |
— |
enableCommandApi |
enable_command_api |
No | When set to True, you can run odpscmd-specific commands through the JDBC driver. |
False |
skipCheckIfSelect |
skipCheckIfSelect |
No | Skips SQL parsing. Reduces client CPU and memory usage, but may increase latency for non-SELECT statements. | False |
Offline mode parameters
| URL key | Property key | Required | Description | Default |
|---|---|---|---|---|
autoLimitFallback |
auto_limit_fallback |
No | When set to True and a no download permission error occurs in offline mode, downloads fall back to a maximum of 10,000 records. |
False |
MaxCompute Query Acceleration (MaxQA/MCQA 1.0) parameters
Enable MaxQA/MCQA 1.0 mode by setting interactiveMode=True. The parameters below apply only in this mode.
Basic parameters:
| URL key | Property key | Required | Description | Default |
|---|---|---|---|---|
interactiveMode |
interactive_mode |
No | Enables MaxCompute Query Acceleration (MaxQA/MCQA 1.0). | False |
executeProject |
execute_project_name |
No | The name of the MaxCompute project where the SQL task runs. | — |
tunnelRetryTime |
tunnel_retry_time |
No | Maximum number of Tunnel retries for SQLExecutor. | 6 |
attachTimeout |
attach_timeout |
No | Connection timeout when establishing a MaxQA/MCQA 1.0 session. Unit: seconds. | 60 |
fallbackQuota |
fallback_quota |
No | Quota to use when the MaxQA/MCQA 1.0 job falls back to offline mode. If not set, the project's default quota is used. | — |
quotaName |
quota_name |
No | Quota computing resources for the MaxQA job. | — |
Result limit parameters:
| URL key | Property key | Required | Description | Default |
|---|---|---|---|---|
enableLimit |
enable_limit |
No | Limits the number of records returned per query. When True, download permission checks are bypassed and results are capped at 10,000 rows. |
True |
instanceTunnelMaxRecord |
instance_tunnel_max_record |
No | Maximum number of records in the result set. Takes effect only when enableLimit=False. |
— |
instanceTunnelMaxSize |
instance_tunnel_max_size |
No | Maximum size of the result set. Unit: bytes. | — |
autoSelectLimit |
auto_select_limit |
No | Maximum rows per query. The default in Alibaba Cloud's elastic computing environment is 1,000,000 rows. To query more rows, set this parameter. Takes effect only when enableLimit=False. When using JDBC V3.2.29 or later, setting autoSelectLimit automatically sets enableLimit=False. |
— |
Fallback parameters:
These parameters control when a MaxQA/MCQA 1.0 job falls back to offline mode.
| URL key | Property key | Description | Default |
|---|---|---|---|
fallbackForUnknownError |
fallback_for_unknownerror |
Falls back on unknown errors. | True |
fallbackForResourceNotEnough |
fallback_for_resourcenotenough |
Falls back when resources are insufficient. | True |
fallbackForUpgrading |
fallback_for_upgrading |
Falls back during upgrades. | True |
fallbackForRunningTimeout |
fallback_for_runningtimeout |
Falls back on connection timeout. | True |
fallbackForUnsupportedFeature |
fallbackForUnsupportedFeature |
Falls back for features not supported by MCQA. | True |
alwaysFallback |
always_fallback |
Falls back in all the above scenarios. Requires JDBC V3.2.3 or later. | False |
disableFallback |
disable_fallback |
Disables fallback in all scenarios. | False |
Code examples
All examples read AccessKey credentials from environment variables. Do not hard-code credentials in your source code.
Create a table and query 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";
// Read credentials from environment variables to avoid exposing them in code.
private static String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
public static void main(String[] args) {
try {
Class.forName(DRIVER_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
try (
Connection conn = DriverManager.getConnection(
"jdbc:odps:<maxcompute_endpoint>?project=<maxcompute_project>",
Main.accessId, Main.accessKey);
Statement stmt = conn.createStatement()
) {
// Create a table
final String tableName = "jdbc_test";
stmt.execute("DROP TABLE IF EXISTS " + tableName);
stmt.execute("CREATE TABLE " + tableName + " (key BIGINT, value STRING)");
// Query metadata
DatabaseMetaData metaData = conn.getMetaData();
System.out.println("product = " + metaData.getDatabaseProductName());
System.out.println("jdbc version = "
+ metaData.getDriverMajorVersion() + ", "
+ metaData.getDriverMinorVersion());
try (ResultSet tables = metaData.getTables(null, "default", tableName, null)) {
while (tables.next()) {
String name = tables.getString("TABLE_NAME");
System.out.println("inspecting table: " + name);
try (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") + ")");
}
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Expected output:
product = MaxCompute/ODPS
jdbc version = 3, 8
inspecting table: jdbc_test
key BIGINT(-5)
value STRING(12)
Insert a single row
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";
private static String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
public static void main(String[] args) {
try {
Class.forName(DRIVER_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
try (
Connection conn = DriverManager.getConnection(
"jdbc:odps:<maxcompute_endpoint>?project=<maxcompute_project>",
Main.accessId, Main.accessKey);
Statement stmt = conn.createStatement()
) {
String dml = "INSERT INTO jdbc_test VALUES(1, \"foo\")";
int ret = stmt.executeUpdate(dml);
assert ret == 1;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Insert multiple rows in a batch
Use PreparedStatement.executeBatch() to insert multiple rows in one operation.
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";
private static String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
public static void main(String[] args) {
try {
Class.forName(DRIVER_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
try (
Connection conn = DriverManager.getConnection(
"jdbc:odps:<maxcompute endpoint>?project=<maxcompute project>",
Main.accessId, Main.accessKey);
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO jdbc_test VALUES(?, ?)")
) {
// First batch
pstmt.setLong(1, 1L);
pstmt.setString(2, "foo");
pstmt.addBatch();
// Second batch
pstmt.setLong(1, 2L);
pstmt.setString(2, "bar");
pstmt.addBatch();
int[] ret = pstmt.executeBatch();
assert ret[0] == 1;
assert ret[1] == 1;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
executeBatch() does not support batch writes to clustered tables, including Transaction Table 2.0.
For standard partitioned tables, specify the target partition in the INSERT INTO statement. Example:
-- Create a partitioned table
CREATE TABLE IF NOT EXISTS sale_detail
(
shop_name STRING,
customer_id STRING,
total_price DOUBLE
)
PARTITIONED BY (sale_date STRING, region STRING);
-- Insert into a specific partition
INSERT INTO sale_detail PARTITION(sale_date='20240219', region='hangzhou') VALUES(?, ?, ?)
Query data from a table
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";
private static String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
public static void main(String[] args) {
try {
Class.forName(DRIVER_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
try (
Connection conn = DriverManager.getConnection(
"jdbc:odps:<maxcompute endpoint>?project=<maxcompute project>",
accessId, accessKey);
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("SELECT * FROM JDBC_TEST")
) {
while (rset.next()) {
System.out.println(rset.getInt(1) + "\t" + rset.getString(2));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
OdpsStatementsupportsexecute(sql),executeQuery(sql), andexecuteUpdate(sql). Theexecute(sql)andexecuteQuery(sql)methods also accept metadata commands such asdesc table,show tables, andshow partitions.