Partilhar via


Driver JDBC da Microsoft para Microsoft Fabric Data Engineering (versão prévia)

Observação

Esta funcionalidade está em pré-visualização.

JDBC (Java Database Connectivity) é um padrão amplamente adotado que permite que aplicações clientes se liguem e trabalhem com dados provenientes de bases de dados e plataformas de big data.

O Microsoft JDBC Driver for Fabric Data Engineering permite-lhe ligar, consultar e gerir cargas de trabalho Spark no Microsoft Fabric com a fiabilidade e simplicidade do padrão JDBC. Baseado nas APIs Livy do Microsoft Fabric, o driver oferece conectividade Spark SQL segura e flexível às suas aplicações Java e ferramentas de BI. Esta integração permite-lhe submeter e executar código Spark diretamente, sem necessidade de criar artefatos separados de caderno ou definição de tarefa Spark.

Principais características

  • Compatível com JDBC 4.2: Implementação completa da especificação JDBC 4.2
  • Autenticação Microsoft Entra ID: Múltiplos fluxos de autenticação, incluindo credenciais interativas de cliente e autenticação baseada em certificados
  • Pooling de Ligações Empresariais: Pooling de ligações integrado com monitorização de saúde e recuperação automática
  • Suporte Nativo de Consultas SQL Spark: Execução direta de instruções SQL Spark sem tradução
  • Suporte Abrangente de Tipos de Dados: Suporte para todos os tipos de dados SQL Spark, incluindo tipos complexos (ARRAY, MAP, STRUCT)
  • Pré-busca de Conjuntos de Resultados Assíncronos: Carregamento de dados em segundo plano para melhorar o desempenho
  • Padrão de Disjuntor: Proteção contra falhas em cascata com repetição automática
  • Reconexão Automática: Recuperação transparente de sessão em falhas de ligação
  • Suporte a Proxy: Configuração de proxy HTTP e SOCKS para ambientes empresariais

Pré-requisitos

Antes de usar o Microsoft JDBC Driver para Engenharia de Dados Microsoft Fabric, certifique-se de que tem:

  • Java Development Kit (JDK): Versão 11 ou superior (recomendado Java 21)
  • Acesso Microsoft Fabric: Acesso a um espaço de trabalho Microsoft Fabric
  • Azure Entra ID Credentials: Credenciais apropriadas para autenticação
  • IDs de espaço de trabalho e casa do lago: identificadores GUID para o seu espaço de trabalho Fabric e casa do lago

Download e Instalação

O Microsoft JDBC Driver for Microsoft Fabric Data Engineering versão 1.0.0 é a versão pública de pré-visualização e suporta Java 11, 17 e 21. Estamos continuamente a melhorar o suporte da conectividade Java e recomendamos que trabalhe com a versão mais recente do driver JDBC da Microsoft.

  1. Descarregue o ficheiro zip ou tar dos links acima.
  2. Extrai o ficheiro descarregado para aceder aos ficheiros JAR do driver.
  3. Selecione o ficheiro JAR que corresponde à sua versão do JRE:
    • Para Java 11: ms-sparksql-jdbc-1.0.0.jre11.jar
    • Para Java 17: ms-sparksql-jdbc-1.0.0.jre17.jar
    • Para Java 21: ms-sparksql-jdbc-1.0.0.jre21.jar
  4. Adicione o ficheiro JAR selecionado ao percurso de classes da sua aplicação.
  5. Para clientes JDBC, configure a classe do driver JDBC: com.microsoft.spark.livy.jdbc.LivyDriver

Exemplo de Início Rápido

Este exemplo demonstra como se ligar ao Microsoft Fabric e executar uma consulta usando o Microsoft JDBC Driver for Microsoft Fabric Data Engineering. Antes de executar este código, certifique-se de que cumpriu os pré-requisitos e instalou o driver.

import java.sql.*;

public class QuickStartExample {
    public static void main(String[] args) {
        // Connection string with required parameters
        String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
                     "FabricWorkspaceID=<workspace-id>;" +
                     "FabricLakehouseID=<lakehouse-id>;" +
                     "AuthFlow=2;" +  // Interactive browser authentication
                     "LogLevel=INFO";
        
        try (Connection conn = DriverManager.getConnection(url)) {
            // Execute a simple query
            try (Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT 'Hello from Fabric!' as message")) {
                
                if (rs.next()) {
                    System.out.println(rs.getString("message"));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Formato de Cadeia de Conexão

Cadeia de Conexão Básica

O Driver Microsoft JDBC para Engenharia de Dados Microsoft Fabric utiliza o seguinte formato de string de ligação:

jdbc:fabricspark://<hostname>[:<port>][;<parameter1>=<value1>;<parameter2>=<value2>;...]

Componentes da Corda de Ligação

Componente Description Example
Protocol Identificador do protocolo URL JDBC jdbc:fabricspark://
Nome do host Nome de host do endpoint Microsoft Fabric api.fabric.microsoft.com
Porto Número de porta opcional (padrão: 443) :443
Parâmetros Pares chave=valor separados por ponto e vírgula FabricWorkspaceID=<guid>

Exemplos de Cordas de Ligação

Conexão Básica (Autenticação Interativa)

jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=2

Com Configuração de Recursos Spark

jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;DriverCores=4;DriverMemory=4g;ExecutorCores=4;ExecutorMemory=8g;NumExecutors=2;AuthFlow=2

Com as Propriedades da Sessão Spark

jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;spark.sql.adaptive.enabled=true;spark.sql.shuffle.partitions=200;AuthFlow=2

Authentication

O Microsoft JDBC Driver for Microsoft Fabric Data Engineering suporta múltiplos métodos de autenticação através do Microsoft Entra ID (anteriormente Azure Active Directory). A autenticação é configurada usando o AuthFlow parâmetro na cadeia de ligação.

Fluxos de Autenticação

AuthFlow Método de autenticação Caso de uso
0 Azure CLI Credencial Desenvolvimento usando Azure CLI
1 Credenciais do Cliente (Principal de Serviço) Autenticação automatizada/serviço-para-serviço
2 Navegador Interativo Autenticação interativa do utilizador (por defeito)
3 SPN Autenticação da entidade de serviço
4 Baseado em Certificado Autenticação do principal de serviço baseada em certificado
5 Token de Acesso Token de acesso pré-adquirido

Autenticação Interativa do Navegador

Melhor para: Desenvolvimento e aplicações interativas

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=2;" +  // Interactive browser authentication
             "AuthTenantID=<tenant-id>;" +  // Optional
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Parâmetros:

  • AuthFlow=2: Especifica autenticação interativa do navegador
  • AuthTenantID (opcional): Azure tenant ID
  • AuthClientID (opcional): ID da aplicação (cliente)

Comportamento:

  • Abre uma janela do navegador para autenticação do utilizador
  • As credenciais são armazenadas em cache para ligações subsequentes até expirarem
  • Adequado para aplicações de utilizador único

Autenticação de Credenciais do Cliente

Ideal para: Serviços automatizados e tarefas em segundo plano

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=1;" +  // Client credentials authentication
             "AuthClientID=<client-id>;" +
             "AuthClientSecret=<client-secret>;" +
             "AuthTenantID=<tenant-id>;" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Parâmetros Exigidos:

  • AuthFlow=1: Especifica a autenticação das credenciais do cliente
  • AuthClientID: ID da aplicação (cliente) a partir do ID Microsoft Entra
  • AuthClientSecret: Segredo do cliente do Microsoft Entra ID
  • AuthTenantID: Azure tenant ID

Melhores Práticas:

  • Armazenar segredos de forma segura (Azure Key Vault, variáveis de ambiente)
  • Use identidades geridas sempre que possível
  • Alterne os segredos regularmente

Autenticação Baseada em Certificado

Ideal para: aplicações empresariais que requerem autenticação baseada em certificado

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=4;" +  // Certificate-based authentication
             "AuthClientID=<client-id>;" +
             "AuthCertificatePath=/path/to/certificate.pfx;" +
             "AuthCertificatePassword=<certificate-password>;" +
             "AuthTenantID=<tenant-id>;" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Parâmetros Exigidos:

  • AuthFlow=4: Especifica autenticação baseada em certificado
  • AuthClientID: ID da aplicação (cliente)
  • AuthCertificatePath: Caminho para o ficheiro de certificado PFX/PKCS12
  • AuthCertificatePassword: Palavra-passe do certificado
  • AuthTenantID: Azure tenant ID

Autenticação do Service Principal

Ideal para: ambientes sem cabeça e sessões remotas

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=3;" +  // Device code authentication
             "AuthClientID=<client-id>;" +
             "AuthTenantID=<tenant-id>;" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Comportamento:

  • Exibe um código de dispositivo e URL na consola
  • O utilizador visita o URL e insere o código
  • A autenticação é concluída após a verificação do utilizador

Autenticação por Token de Acesso

Melhor para: cenários de autenticação personalizados

// Acquire token through custom mechanism
String accessToken = acquireTokenFromCustomSource();

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=5;" +  // Access token authentication
             "AuthAccessToken=" + accessToken + ";" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Cache de Autenticação

O driver armazena automaticamente em cache os tokens de autenticação para melhorar o desempenho:

// Enable/disable caching (enabled by default)
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=2;" +
             "AuthEnableCaching=true;" +  // Enable token caching
             "AuthCacheTTLMS=3600000";    // Cache TTL: 1 hour

Connection conn = DriverManager.getConnection(url);

Parâmetros de Configuração

Parâmetros necessários

Estes parâmetros devem estar presentes em cada cadeia de conexão:

Parâmetro Tipo Description Example
FabricWorkspaceID Identificador Único Universal (UUID) Identificador de espaço de trabalho Microsoft Fabric <workspace-id>
FabricLakehouseID Identificador Único Universal (UUID) Identificador Microsoft Fabric lakehouse <lakehouse-id>
AuthFlow Número inteiro Tipo de fluxo de autenticação (0-5) 2

Parâmetros opcionais

Configuração da Versão API

Parâmetro Tipo Predefinido Description
FabricVersion Cordão v1 Versão da API Microsoft Fabric
LivyApiVersion Cordão 2023-12-01 Versão da API do Livy

Configuração do ambiente

Parâmetro Tipo Predefinido Description
FabricEnvironmentID Identificador Único Universal (UUID) Nenhum Identificador de ambiente Fabric para referenciar o item de ambiente para a sessão do Spark

Configuração do Spark

Configuração dos Recursos de Sessão

Configure os recursos da sessão Spark para um desempenho ótimo:

Parâmetro Tipo Predefinido Description Example
DriverCores Número inteiro Spark predefinição Número de núcleos de CPU para o driver 4
DriverMemory Cordão Spark predefinição Alocação de memória para o driver 4g
ExecutorCores Número inteiro Spark predefinição Número de núcleos de CPU por executor 4
ExecutorMemory Cordão Spark predefinição Alocação de memória por executor 8g
NumExecutors Número inteiro Spark predefinição Número de executores 2

Example:

DriverCores=4;DriverMemory=4g;ExecutorCores=4;ExecutorMemory=8g;NumExecutors=2

Propriedades Personalizadas da Sessão Spark

Qualquer parâmetro com o prefixo spark. é automaticamente aplicado à sessão Spark:

Exemplos de Configurações do Spark:

spark.sql.adaptive.enabled=true
spark.sql.adaptive.coalescePartitions.enabled=true
spark.sql.shuffle.partitions=200
spark.sql.autoBroadcastJoinThreshold=10485760
spark.dynamicAllocation.enabled=true
spark.dynamicAllocation.minExecutors=1
spark.dynamicAllocation.maxExecutors=10
spark.executor.memoryOverhead=1g

Motor de Execução Nativo (NEE):

spark.nee.enabled=true

Exemplo completo:

jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<guid>;FabricLakehouseID=<guid>;DriverMemory=4g;ExecutorMemory=8g;NumExecutors=2;spark.sql.adaptive.enabled=true;spark.nee.enabled=true;AuthFlow=2

Configuração do Pool de Ligações HTTP

Configure o agrupamento de ligações HTTP para um desempenho de rede ótimo:

Parâmetro Tipo Predefinido Description
HttpMaxTotalConnections Número inteiro 100 Número máximo total de ligações HTTP
HttpMaxConnectionsPerRoute Número inteiro 50 Ligações máximas por rota
HttpConnectionTimeoutInSeconds Número inteiro 30 Tempo limite de conexão
HttpSocketTimeoutInSeconds Número inteiro 60 Timeout de leitura do socket
HttpReadTimeoutInSeconds Número inteiro 60 Tempo limite de leitura HTTP
HttpConnectionRequestTimeoutSeconds Número inteiro 30 Pedido de ligação excedeu o tempo limite no pool
HttpEnableKeepAlive booleano true Ativar HTTP keep-alive
HttpKeepAliveTimeoutSeconds Número inteiro 60 Tempo limite de ligação ativa
HttpFollowRedirects booleano true Seguir redirecionamentos HTTP
HttpUseAsyncIO booleano false Utilizar E/S HTTP assíncrona

Example:

HttpMaxTotalConnections=200;HttpMaxConnectionsPerRoute=100;HttpConnectionTimeoutInSeconds=60

Configuração do Proxy

Configure as definições de proxy HTTP e SOCKS para ambientes empresariais:

Parâmetro Tipo Predefinido Description
UseProxy booleano false Ativar proxy
ProxyTransport Cordão http Tipo de transporte proxy (http/tcp)
ProxyHost Cordão Nenhum Nome de host proxy
ProxyPort Número inteiro Nenhum Porta proxy
ProxyAuthEnabled booleano false Ativar autenticação por proxy
ProxyUsername Cordão Nenhum Nome de utilizador de autenticação por proxy
ProxyPassword Cordão Nenhum Palavra-passe de autenticação por proxy
ProxyAuthScheme Cordão basic Esquema de autenticação (básico/digest/ntlm)
ProxySocksVersion Número inteiro 5 Versão SOCKS (4/5)

Exemplo de Proxy HTTP:

UseProxy=true;ProxyTransport=http;ProxyHost=proxy.company.com;ProxyPort=8080;ProxyAuthEnabled=true;ProxyUsername=user;ProxyPassword=pass

Exemplo de Proxy SOCKS:

UseProxy=true;ProxyTransport=tcp;ProxyHost=socks.company.com;ProxyPort=1080;ProxySocksVersion=5

Configuração de registro em log

Parâmetro Tipo Predefinido Description
LogLevel Cordão INFO Nível de registro: TRACE, DEBUG, INFO, WARN, ERROR

Example:

LogLevel=DEBUG

Localização do Registo Predefinido:

${user.home}/.microsoft/livy-jdbc-driver/driver.log

Configuração do Log Personalizado: Utilize um ficheiro log4j2.xml ou logback.xml personalizado no teu classpath.


Exemplos de uso

Conexão Básica

import java.sql.*;

public class BasicConnectionExample {
    public static void main(String[] args) {
        String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
                     "FabricWorkspaceID=<workspace-id>;" +
                     "FabricLakehouseID=<lakehouse-id>;" +
                     "AuthFlow=2";
        
        try (Connection conn = DriverManager.getConnection(url)) {
            System.out.println("Connected successfully!");
            System.out.println("Database: " + conn.getMetaData().getDatabaseProductName());
            System.out.println("Driver: " + conn.getMetaData().getDriverName());
            System.out.println("Driver Version: " + conn.getMetaData().getDriverVersion());
        } catch (SQLException e) {
            System.err.println("Connection failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Executando consultas

Consulta simples

public void executeSimpleQuery(Connection conn) throws SQLException {
    String sql = "SELECT current_timestamp() as now";
    
    try (Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(sql)) {
        
        if (rs.next()) {
            Timestamp now = rs.getTimestamp("now");
            System.out.println("Current timestamp: " + now);
        }
    }
}

Consulta com filtro

public void executeQueryWithFilter(Connection conn) throws SQLException {
    String sql = "SELECT * FROM sales WHERE amount > 1000 ORDER BY amount DESC";
    
    try (Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(sql)) {
        
        while (rs.next()) {
            int id = rs.getInt("id");
            double amount = rs.getDouble("amount");
            Date date = rs.getDate("sale_date");
            
            System.out.printf("ID: %d, Amount: %.2f, Date: %s%n", 
                            id, amount, date);
        }
    }
}

Consulta com Limite

public void executeQueryWithLimit(Connection conn) throws SQLException {
    String sql = "SELECT * FROM customers LIMIT 10";
    
    try (Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(sql)) {
        
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();
        
        // Print column names
        for (int i = 1; i <= columnCount; i++) {
            System.out.print(metaData.getColumnName(i) + "\t");
        }
        System.out.println();
        
        // Print rows
        while (rs.next()) {
            for (int i = 1; i <= columnCount; i++) {
                System.out.print(rs.getString(i) + "\t");
            }
            System.out.println();
        }
    }
}

Trabalhar com Conjuntos de Resultados

public void navigateResultSet(Connection conn) throws SQLException {
    String sql = "SELECT id, name, amount FROM orders";
    
    try (Statement stmt = conn.createStatement(
            ResultSet.TYPE_SCROLL_INSENSITIVE,
            ResultSet.CONCUR_READ_ONLY);
         ResultSet rs = stmt.executeQuery(sql)) {
        
        // Move to first row
        if (rs.first()) {
            System.out.println("First row: " + rs.getString("name"));
        }
        
        // Move to last row
        if (rs.last()) {
            System.out.println("Last row: " + rs.getString("name"));
            System.out.println("Total rows: " + rs.getRow());
        }
        
        // Move to specific row
        if (rs.absolute(5)) {
            System.out.println("Row 5: " + rs.getString("name"));
        }
    }
}

Processamento de Grandes Conjuntos de Resultados

public void processLargeResultSet(Connection conn) throws SQLException {
    String sql = "SELECT * FROM large_table";
    
    try (Statement stmt = conn.createStatement()) {
        // Set fetch size for efficient memory usage
        stmt.setFetchSize(1000);
        
        try (ResultSet rs = stmt.executeQuery(sql)) {
            int rowCount = 0;
            while (rs.next()) {
                // Process row
                processRow(rs);
                rowCount++;
                
                if (rowCount % 10000 == 0) {
                    System.out.println("Processed " + rowCount + " rows");
                }
            }
            System.out.println("Total rows processed: " + rowCount);
        }
    }
}

private void processRow(ResultSet rs) throws SQLException {
    // Process individual row
}

Utilização de Declarações Preparadas

public void usePreparedStatement(Connection conn) throws SQLException {
    String sql = "SELECT * FROM products WHERE category = ? AND price > ?";
    
    try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        // Set parameters
        pstmt.setString(1, "Electronics");
        pstmt.setDouble(2, 100.0);
        
        try (ResultSet rs = pstmt.executeQuery()) {
            while (rs.next()) {
                String name = rs.getString("name");
                double price = rs.getDouble("price");
                System.out.printf("Product: %s, Price: $%.2f%n", name, price);
            }
        }
    }
}

Operações em Lote

public void executeBatchInsert(Connection conn) throws SQLException {
    String sql = "INSERT INTO logs (timestamp, level, message) VALUES (?, ?, ?)";
    
    try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        conn.setAutoCommit(false);  // Disable auto-commit for batch
        
        // Add multiple statements to batch
        for (int i = 0; i < 1000; i++) {
            pstmt.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
            pstmt.setString(2, "INFO");
            pstmt.setString(3, "Log message " + i);
            pstmt.addBatch();
            
            // Execute batch every 100 statements
            if (i % 100 == 0) {
                pstmt.executeBatch();
                pstmt.clearBatch();
            }
        }
        
        // Execute remaining statements
        pstmt.executeBatch();
        conn.commit();
        
        System.out.println("Batch insert completed successfully");
    } catch (SQLException e) {
        conn.rollback();
        throw e;
    } finally {
        conn.setAutoCommit(true);
    }
}

Mapeamento de Tipos de Dados

O driver mapeia os tipos de dados SQL do Spark para tipos SQL JDBC e tipos Java:

Tipo SQL Spark Tipo SQL JDBC Tipo Java Observações
BOOLEAN BOOLEAN Boolean
BYTE TINYINT Byte
SHORT SMALLINT Short
INT INTEGER Integer
LONG BIGINT Long
FLOAT FLOAT Float
DOUBLE DOUBLE Double
DECIMAL DECIMAL BigDecimal Precisão e escala preservadas
STRING VARCHAR String
VARCHAR(n) VARCHAR String
CHAR(n) CHAR String
BINARY BINARY byte[]
DATE DATE java.sql.Date
TIMESTAMP TIMESTAMP java.sql.Timestamp
ARRAY VARCHAR String Serializado como JSON
MAP VARCHAR String Serializado como JSON
STRUCT VARCHAR String Serializado como JSON