Este guia explica como baixar o driver JDBC do MaxCompute e conectar-se ao service. Inclui códigos de exemplo para ajudar você a começar.
Precauções
-
Para executar instruções SQL e obter resultados com o driver JDBC do MaxCompute, atenda aos seguintes requisitos:
Seja membro de um projeto.
Tenha a permissão CREATE INSTANCE no projeto.
-
Tenha as permissões SELECT e DOWNLOAD na tabela desejada.
NotaNo MaxCompute JDBC V1.9 ou anterior, o sistema cria automaticamente uma tabela temporária para cada consulta. Use comandos Tunnel para obter os resultados dessa tabela temporária. Para usar essas versões, é necessária a permissão CREATE TABLE.
No MaxCompute JDBC V2.2 ou posterior, não há criação automática de tabela temporária para cada consulta. Chame a interface InstanceTunnel para obter os resultados, independentemente da permissão CREATE TABLE.
Para mais informações sobre permissões do MaxCompute, consulte MaxCompute permissions.
O MaxCompute oferece o recurso de proteção de dados. Se esse recurso estiver ativado em um projeto, não será possível mover dados para fora dele. Caso utilize uma versão do MaxCompute JDBC anterior à V2.4, nenhum
result setspoderá ser obtido. Se usar o MaxCompute JDBC V2.4 ou posterior, o número de linhas de resultado retornadas não poderá exceder o valor do parâmetro READ_TABLE_MAX_ROW. Para mais detalhes sobre esse parâmetro, consulte Project operations. Para saber mais sobre o recurso de proteção de dados, veja Project data protection.
-
A edição de tipos de dados do MaxCompute V2.0 suporta mais tipos, como TINYINT, SMALLINT, DATETIME, TIMESTAMP, ARRAY, MAP e STRUCT. Para utilizar esses novos tipos, execute o comando abaixo para ativar a edição de tipos de dados do MaxCompute V2.0. Para mais informações, consulte Data type version guide.
set odps.sql.type.system.odps2=true Para JDBC V3.4.1 e posteriores, se você tiver consultas SQL longas (maiores que 1 KB), controle cuidadosamente a concorrência. Por exemplo, ao usar uma instância ECS com 8 vCPUs e 16,0 GiB de memória, a concorrência não deve ultrapassar 100. Caso não consiga controlar a concorrência de forma eficaz, atualize o JDBC para V3.8.8 ou V3.9.3 e defina
skipCheckIfSelect=truepara desativar o recurso de análise de SQL. Para mais informações sobre esse recurso, consulte Version updates.
Baixe o driver JDBC
Obtenha os pacotes JAR do MaxCompute para diferentes versões no OSS, no GitHub ou no repositório Maven. Recomendamos baixar o pacote JAR que inclui todas as dependências (jar-with-dependencies).
O exemplo a seguir mostra a dependência do Project Object Model (POM) para usar o driver JDBC do MaxCompute com Maven.
<dependency>
<groupId>com.aliyun.odps</groupId>
<artifactId>odps-jdbc</artifactId>
<version>3.8.6</version>
<classifier>jar-with-dependencies</classifier>
</dependency>
O driver JDBC do MaxCompute é um projeto open source disponível em aliyun-odps-jdbc.
Suas contribuições para o desenvolvimento e melhoria do driver JDBC são bem-vindas. Relate problemas na página Issues ou contribua com melhorias de código por meio de Pull requests. Ao usar Issues e Pull requests, siga os requisitos de modelo do projeto.
Parâmetros JDBC
Configure o JDBC usando parâmetros de URL e objetos Properties. Os objetos Properties têm prioridade maior e substituem os parâmetros da URL.
Se a chave da URL contiver odps_config=config_file, o JDBC lê config_file como parâmetros Properties.
-
Parâmetros básicos
Chave da URL
Chave da propriedade
Obrigatório
Descrição
project
project_name
Sim
Nome do projeto MaxCompute.
accessId
access_id
Sim
AccessKey ID da sua conta Alibaba Cloud.
Obtenha seu AccessKey ID na página AccessKey Management.
accessKey
access_key
Sim
AccessKey secret da sua conta Alibaba Cloud.
Obtenha seu AccessKey secret na página AccessKey Management.
logview
logview_host
Não
URL do LogView do MaxCompute. O valor é fixo em
http://logview.odps.aliyun.com.tunnelEndpoint
tunnel_endpoint
Não
Endpoint do service MaxCompute Tunnel.
Para os endpoints do Tunnel de cada região e tipo de rede, consulte Endpoints.
-
Parâmetros de configuração de log
Chave da URL
Chave da propriedade
Obrigatório
Descrição
enableOdpsLogger
enable_odps_logger
Não
Define se o logger JDBC do MaxCompute deve ser ativado. Valores válidos:
False (padrão): Desativa o logger.
True: Ativado. Os logs são gravados no arquivo
jdbc.logno diretório do pacote JAR.
logConfFile
log_conf_file
Não
Especifique um arquivo de configuração SLF4J adicional para configurar flexivelmente a saída de log, como o arquivo de saída e logLevel. Este método exige adicionar as seguintes dependências ao arquivo
pom.xmldo seu projeto:<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>Para um exemplo de configuração, consulte Exemplo de arquivo de configuração.
logLevel
log_level
Não
Nível de log da saída. Valor padrão: INFO.
-
Outros parâmetros
Chave da URL
Chave da propriedade
Obrigatório
Descrição
stsToken
sts_token
Não
Token STS da Alibaba Cloud.
charset
charset
Não
Conjunto de caracteres para entrada e saída. Valor padrão: UTF-8.
useProjectTimeZone
use_project_time_zone
Não
Define se a propriedade
odps.sql.timezonedo projeto deve ser usada. Valores válidos:False (padrão): Não usa a propriedade.
True: Usa a propriedade.
NotaTambém é possível especificar o fuso horário em uma instrução usando
set odps.sql.timezone=xxx.Ordem de prioridade: Instrução > projeto > null.
disableConnectionSetting
disable_connection_setting
Não
Define se é permitido definir parâmetros SQL para uma conexão. Valores válidos:
False (padrão): Não permitido.
True: Permitido.
Quando este parâmetro é definido como true, o comando
set xxxaplica-se tanto à instrução quanto à conexão. Caso contrário, aplica-se apenas à instrução.settings
settings
Não
String JSON para o
sql settingpadrão global. Exemplo:{"key":"value"}.tableList
table_list
Não
Nomes das tabelas do MaxCompute. Formato:
projectname.tablename,projectname1.tablename1.connectTimeout
connect_timeout
Não
Tempo limite para estabelecer uma conexão de rede. Valor padrão: 10 segundos (s).
readTimeout
read_timeout
Não
Tempo limite para leitura de dados de uma conexão de rede. Valor padrão: 120 segundos (s).
NotaO tempo limite total para cada solicitação de API RESTful é a soma de connectTimeout e readTimeout, cujo padrão é 130 segundos. O driver tenta novamente cada solicitação até 3 vezes.
Para ajustar o tempo limite de conexão para solicitações de API RESTful, modifique o parâmetro readTimeout.
enableCommandApi
enable_command_api
Não
Define se a API de comando deve ser usada. Valores válidos:
False (padrão): A API de comando não é usada.
True: A API de comando é usada.
Quando ativado, é possível executar comandos no JDBC que normalmente são exclusivos do odpscmd.
httpsCheck
https_check
Não
Define se a verificação de certificado HTTPS deve ser realizada. Valores válidos:
False (padrão): A verificação não é realizada.
True: A verificação é realizada.
tunnelConnectTimeout
tunnel_connect_timeout
Não
Período de tempo limite de conexão para o Tunnel durante o download de dados. Valor padrão: 180 segundos (s).
tunnelReadTimeout
tunnel_read_timeout
Não
Período de tempo limite de leitura para o Tunnel durante o download de dados. Valor padrão: 300 segundos (s).
skipCheckIfSelect
skipCheckIfSelect
Não
Define se a análise de SQL deve ser ignorada. Valores válidos:
False (padrão): Não ignora a análise.
True: Ignora a análise.
NotaIgnorar a análise pode reduzir o consumo de cpu e memória no lado do cliente, mas pode aumentar a latência para instruções que não sejam SELECT.
-
Parâmetros não MCQA (efetivos apenas no modo offline)
Chave da URL
Chave da propriedade
Obrigatório
Descrição
autoLimitFallback
auto_limit_fallback
Não
Fallback automático de limite. Valores válidos:
False (padrão): Não faz fallback.
True: Faz fallback. No modo offline, quando o Tunnel reporta uma exceção
no download permission, o driver faz fallback automaticamente e limita o número de registros baixados a 10.000.
-
Parâmetros MaxQA/MCQA 1.0 (efetivos apenas para MaxQA/MCQA 1.0)
Configuração básica
False (padrão): Desativado.
True: Ativado.
-
Parâmetros relacionados a limites
Chave da URL
Chave da propriedade
Obrigatório
Descrição
instanceTunnelMaxRecord
instance_tunnel_max_record
Não
Número máximo de registros no conjunto de resultados.
NotaEste parâmetro só entra em vigor quando o parâmetro enableLimit está definido como False.
instanceTunnelMaxSize
instance_tunnel_max_size
Não
Tamanho máximo do conjunto de resultados. Unidade: byte.
autoSelectLimit
auto_select_limit
Não
Limite automático de consulta.
Por padrão, é possível consultar no máximo 1.000.000 linhas em ambientes de nuvem pública da Alibaba Cloud. Para consultar mais dados, configure este parâmetro.
NotaEste parâmetro só entra em vigor quando o parâmetro enableLimit está definido como False.
Para JDBC V3.2.29 e posteriores, se você definir o parâmetro autoSelectLimit, o parâmetro enableLimit será automaticamente definido como False.
enableLimit
enable_limit
Não
Define se o limite deve ser ativado. Valores válidos:
False: O limite não está ativado.
True (padrão): O limite está ativado.
Se ativado, a permissão de download não é verificada e os conjuntos de resultados são limitados a 10.000 registros por padrão.
-
Parâmetros relacionados a fallback
Chave da URL
Chave da propriedade
Obrigatório
Descrição
fallbackForUnknownError
fallback_for_unknownerror
Não
Define se deve haver fallback para o modo offline quando ocorrer um erro desconhecido. Valores válidos:
False: Não faz fallback.
True (padrão): Faz fallback.
fallbackForResourceNotEnough
fallback_for_resourcenotenough
Não
Define se deve haver fallback para o modo offline quando os recursos forem insuficientes. Valores válidos:
False: Não faz fallback.
True (padrão): Faz fallback.
fallbackForUpgrading
fallback_for_upgrading
Não
Define se deve haver fallback para o modo offline durante uma atualização. Valores válidos:
False: Não faz fallback.
True (padrão): Faz fallback.
fallbackForRunningTimeout
fallback_for_runningtimeout
Não
Define se deve haver fallback para o modo offline quando um comando de operação atingir o tempo limite. Valores válidos:
False: Não faz fallback.
True (padrão): Faz fallback.
fallbackForUnsupportedFeature
fallback_for_unsupported_feature
Não
Define se deve haver fallback para o modo offline quando um recurso MCQA não suportado for usado. Valores válidos:
False: Não faz fallback.
True (padrão): Faz fallback.
alwaysFallback
always_fallback
Não
Define se deve haver fallback para o modo offline em todos os cenários anteriores. Valores válidos:
False (padrão): Não faz fallback.
True: Faz fallback.
NotaEste parâmetro é suportado apenas no JDBC V3.2.3 e posteriores.
disableFallback
disable_fallback
Não
Define se o fallback para o modo offline deve ser desativado em todos os cenários anteriores. Valores válidos:
False (padrão): Faz fallback.
True: Não faz fallback.
fallbackQuota
fallback_quota
Não
Nome da cota para a qual uma tarefa MCQA faz fallback. Se não configurada, a cota padrão do projeto é utilizada.
Chave da URL
Chave da propriedade
Obrigatório
Descrição
interactiveMode
interactive_mode
Não
Define se o MaxQA/MCQA 1.0 deve ser ativado. Valores válidos:
executeProject
execute_project_name
Não
Nome do projeto MaxCompute onde a tarefa SQL é realmente executada.
tunnelRetryTime
tunnel_retry_time
Não
Número de tentativas do Tunnel para SQLExecutor. Valor padrão: 6.
attachTimeout
attach_timeout
Não
Período de tempo limite para estabelecer uma conexão MCQA 1.0. Valor padrão: 60 segundos (s).
fallbackQuota
fallback_quota
Não
Cota a ser usada quando uma tarefa MCQA 1.0 faz fallback. Se não configurada, a cota padrão do projeto é utilizada.
quotaName
quota_name
Não
Cota de recursos de computação usada pela tarefa MaxQA.
Conectar ao MaxCompute
-
Carregue o driver JDBC do MaxCompute.
Class.forName("com.aliyun.odps.jdbc.OdpsDriver"); -
Crie uma conexão usando DriverManager.
Connection cnct = DriverManager.getConnection(url, accessId, accessKey);-
url: A URL deve estar no seguinte formato:
jdbc:odps:<maxcompute_endpoint>?project=<maxcompute_project_name>[&useProjectTimeZone={true|false}]. Os parâmetros são descritos da seguinte forma:<maxcompute_endpoint>: O endpoint do service MaxCompute para a região. Por exemplo, o endpoint público para a região China (Hangzhou) é
http://service.cn-hangzhou.maxcompute.aliyun.com/api. Para mais informações, consulte Endpoints.<maxcompute_project_name>: O nome do projeto MaxCompute.
useProjectTimeZone: Define se o fuso horário do projeto MaxCompute deve ser usado.
Exemplo:
jdbc:odps:http://service.cn-hangzhou.maxcompute.aliyun.com/api?project=test_project&useProjectTimeZone=true; accessId: O AccessKey ID da sua conta Alibaba Cloud.
-
accessKey: O AccessKey secret correspondente ao AccessKey ID.
NotaPara criar e visualizar um AccessKey ID e um AccessKey secret, consulte Prepare an Alibaba Cloud account.
-
-
Execute uma consulta.
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 record a closed exception } } }
Código de exemplo
-
Excluir uma tabela, criar uma tabela e obter metadados
NotaSe você adicionar a dependência JDBC ao seu projeto, não adicione a dependência sdk separadamente. A dependência JDBC inclui o sdk necessário, e adicioná-lo separadamente pode causar erros de incompatibilidade de versão.
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"; // An Alibaba Cloud account's AccessKey pair has permissions for all API operations, which is a security risk. We strongly recommend using a RAM user for API access or routine O&M. To create a RAM user, log on to the RAM console. // This example stores the AccessKey ID and AccessKey secret in environment variables. You can also store them in a configuration file based on your business requirements. // For security, do not hardcode the AccessKey ID and AccessKey secret in your 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)"); // get meta data 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(); } } }Saída de exemplo:
product = MaxCompute/ODPS jdbc version = 3, 8 inspecting table: jdbc_test key BIGINT(-5) value STRING(12) -
Atualize uma tabela
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"; // An Alibaba Cloud account's AccessKey pair has permissions for all API operations, which is a security risk. We strongly recommend using a RAM user for API access or routine O&M. To create a RAM user, log on to the RAM console. // This example stores the AccessKey ID and AccessKey secret in environment variables. You can also store them in a configuration file based on your business requirements. // For security, do not hardcode the AccessKey ID and AccessKey secret in your 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() ) { // 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; } catch (SQLException e) { e.printStackTrace(); } } } -
Atualize uma tabela em lote
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"; // An Alibaba Cloud account's AccessKey pair has permissions for all API operations, which is a security risk. We strongly recommend using a RAM user for API access or routine O&M. // This example stores the AccessKey ID and AccessKey secret in environment variables. You can also store them in a configuration file based on your business requirements. // For security, do not hardcode the AccessKey ID and AccessKey secret in your 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); 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(); } } }NotaO método executeBatch não suporta gravações em lote em tabelas clusterizadas, como as tabelas Transaction Table 2.0.
-
Para gravar dados em uma tabela particionada padrão em lotes, especifique a partição de destino na instrução INSERT INTO. Exemplo:
-- The table creation statement for the partitioned table sale_detail is as follows. create table if not exists sale_detail ( shop_name string, customer_id string, total_price double ) partitioned by (sale_date string, region string); -- Assume that the partition sale_date='20240219', region='hangzhou' already exists. The INSERT INTO statement for batch writes to the partitioned table is as follows. INSERT INTO sale_detail PARTITION(sale_date='20240219', region='hangzhou') VALUES(?, ?, ?)
-
Consultar uma tabela
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"; // An Alibaba Cloud account's AccessKey pair has permissions for all API operations, which is a security risk. We strongly recommend using a RAM user for API access or routine O&M. // This example stores the AccessKey ID and AccessKey secret in environment variables. You can also store them in a configuration file based on your business requirements. // For security, do not hardcode the AccessKey ID and AccessKey secret in your 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>", 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(); } } }NotaOdpsStatement suporta três métodos:
execute(sql),executeQuery(sql)eexecuteUpdate(sql). Os métodosexecute(sql)eexecuteQuery(sql)também suportam três comandos comuns:desc table,show tableseshow partitions.