Compartilhar via


Driver do Microsoft JDBC para Engenharia de Dados do Microsoft Fabric (versão prévia)

Observação

Este recurso está em versão prévia.

O JDBC (Conectividade de Banco de Dados Java) é um padrão amplamente adotado que permite que os aplicativos cliente se conectem e trabalhem com dados de bancos de dados e plataformas de Big Data.

O Microsoft JDBC Driver for Fabric Data Engineering permite que você se conecte, consulte e gerencie cargas de trabalho do Spark no Microsoft Fabric com a confiabilidade e a simplicidade do padrão JDBC. Baseado nas APIs Livy do Microsoft Fabric, o driver fornece conectividade segura e flexível do Spark SQL com seus aplicativos Java e ferramentas de BI. Essa integração permite que você envie e execute o código do Spark diretamente sem a necessidade de criar artefatos separados do Notebook ou da Definição de Trabalho do Spark.

Principais características

  • JDBC 4.2 Compatível: implementação completa da especificação JDBC 4.2
  • Autenticação da ID do Microsoft Entra: vários fluxos de autenticação, incluindo interativas, credenciais do cliente e autenticação baseada em certificado
  • Pooling de conexões corporativas: pool de conexões interna com monitoramento de integridade e recuperação automática
  • Suporte à consulta nativa do Spark SQL: execução direta de instruções SQL do Spark sem tradução
  • Suporte a tipos de dados abrangentes: suporte para todos os tipos de dados SQL do Spark, incluindo tipos complexos (ARRAY, MAP, STRUCT)
  • Pré-busca de Conjunto de Resultados Assíncronos: carregamento de dados em segundo plano para aprimorar o desempenho
  • Padrão de disjuntor: proteção contra falhas em cascata com repetição automática
  • Reconexão automática: recuperação de sessão transparente em falhas de conexão
  • Suporte a proxy: configuração de proxy HTTP e SOCKS para ambientes empresariais

Pré-requisitos

Antes de usar o Microsoft JDBC Driver for Microsoft Fabric Data Engineering, verifique se você tem:

  • JDK (Java Development Kit): versão 11 ou superior (Java 21 recomendado)
  • Microsoft Fabric Access: Acesso a um workspace do Microsoft Fabric
  • Credenciais de ID do Azure Entra: credenciais apropriadas para autenticação
  • IDs do Workspace e Lakehouse: identificadores GUID para o seu Workspace do Fabric e Lakehouse

Baixar e instalar

O Microsoft JDBC Driver for Microsoft Fabric Data Engineering versão 1.0.0 é a versão prévia pública e dá suporte ao Java 11, 17 e 21. Estamos melhorando continuamente o suporte à conectividade Java e recomendamos que você trabalhe com a versão mais recente do driver JDBC da Microsoft.

  1. Baixe o arquivo zip ou tar dos links acima.
  2. Extraia o arquivo baixado para acessar os arquivos JAR do driver.
  3. Selecione o arquivo 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 arquivo JAR selecionado ao classpath do aplicativo.
  5. Para clientes JDBC, configure a classe de driver JDBC: com.microsoft.spark.livy.jdbc.LivyDriver

Exemplo de Início Rápido

Este exemplo demonstra como se conectar ao Microsoft Fabric e executar uma consulta usando o Microsoft JDBC Driver for Microsoft Fabric Data Engineering. Antes de executar esse código, verifique se você concluiu 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 da cadeia de conexão

Cadeia de conexão básica

O Microsoft JDBC Driver for Microsoft Fabric Data Engineering usa o seguinte formato de cadeia de conexão:

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

Componentes da cadeia de conexão

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

Exemplo de cadeias de conexão

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

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

Com a configuração de recursos do 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 propriedades de sessão do 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 dá suporte a vários métodos de autenticação por meio da ID do Microsoft Entra (anteriormente Azure Active Directory). A autenticação é configurada usando o AuthFlow parâmetro na cadeia de conexão.

Fluxos de autenticação

AuthFlow Método de autenticação Caso de Uso
0 Credencial do Azure CLI Desenvolvimento usando a CLI do Azure
1 Credenciais do cliente (Entidade de Serviço) Autenticação automatizada/serviço a serviço
2 Navegador Interativo Autenticação interativa do usuário (padrão)
3 SPN Autenticação de entidade de serviço
4 Baseado em Certificado Autenticação de entidade de serviço baseada em certificado
5 Token de acesso Token de acesso pré-adquirido

Autenticação interativa do navegador

Melhor para: desenvolvimento e aplicativos interativos

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 a autenticação interativa do navegador
  • AuthTenantID (opcional): ID do tenant do Azure
  • AuthClientID (opcional): ID do aplicativo (cliente)

Comportamento:

  • Abre uma janela do navegador para autenticação do usuário
  • As credenciais são armazenadas em cache para conexões subsequentes até que elas expirem
  • Adequado para aplicativos de usuário único

Autenticação de credenciais do cliente

Melhor para: serviços automatizados e trabalhos 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 necessários:

  • AuthFlow=1: especifica a autenticação de credenciais do cliente
  • AuthClientID: ID do aplicativo (cliente) da Microsoft Entra ID
  • AuthClientSecret: segredo do cliente do Microsoft Entra ID
  • AuthTenantID: ID do locatário do Azure

Melhores Práticas:

  • Armazenar segredos com segurança (Azure Key Vault, variáveis de ambiente)
  • Usar identidades gerenciadas quando possível
  • Girar segredos regularmente

Autenticação Baseada em Certificado

Melhor para: aplicativos empresariais que exigem 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 necessários:

  • AuthFlow=4: especifica a autenticação baseada em certificado
  • AuthClientID: ID do aplicativo (cliente)
  • AuthCertificatePath: caminho para o arquivo de certificado PFX/PKCS12
  • AuthCertificatePassword: senha do certificado
  • AuthTenantID: ID do locatário do Azure

Autenticação de entidade de serviço

Melhor 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 do dispositivo e uma URL no console
  • O usuário visita a URL e insere o código
  • A autenticação é concluída após a verificação do usuário

Autenticação de 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 tokens de autenticação em cache 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

Esses parâmetros devem estar presentes em todas as cadeias de conexão:

Parâmetro Tipo Description Example
FabricWorkspaceID Identificador Único Universal (UUID) Identificador de workspace do Microsoft Fabric <workspace-id>
FabricLakehouseID Identificador Único Universal (UUID) Identificador do Microsoft Fabric Lakehouse <lakehouse-id>
AuthFlow Integer Tipo de fluxo de autenticação (0-5) 2

Parâmetros opcionais

Configuração de versão da API

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

Configuração do Ambiente

Parâmetro Tipo Padrão Description
FabricEnvironmentID Identificador Único Universal (UUID) None Identificador de ambiente de malha para referenciar item de ambiente para sessão do Spark

Configuração do Spark

Configuração de recursos de sessão

Configurar recursos de sessão do Spark para um desempenho ideal:

Parâmetro Tipo Padrão Description Example
DriverCores Integer Padrão do Spark Número de núcleos de CPU para controlador 4
DriverMemory String Padrão do Spark Alocação de memória para o driver 4g
ExecutorCores Integer Padrão do Spark Número de núcleos de CPU por executor 4
ExecutorMemory String Padrão do Spark Alocação de memória por executor 8g
NumExecutors Integer Padrão do Spark Número de executores 2

Example:

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

Propriedades personalizadas da sessão do Spark

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

Exemplo 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

NEE (Mecanismo de Execução Nativa):

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 conexões HTTP

Configurar o pool de conexões HTTP para um desempenho de rede ideal:

Parâmetro Tipo Padrão Description
HttpMaxTotalConnections Integer 100 Máximo total de conexões HTTP
HttpMaxConnectionsPerRoute Integer 50 Máximo de conexões por rota
HttpConnectionTimeoutInSeconds Integer 30 Tempo limite da conexão
HttpSocketTimeoutInSeconds Integer 60 Tempo limite de leitura do soquete
HttpReadTimeoutInSeconds Integer 60 Tempo limite de leitura HTTP
HttpConnectionRequestTimeoutSeconds Integer 30 Tempo limite de solicitação de conexão do pool
HttpEnableKeepAlive booleano true Manter conexão HTTP ativa
HttpKeepAliveTimeoutSeconds Integer 60 Tempo limite de manter-se vivo
HttpFollowRedirects booleano true Seguir redirecionamentos HTTP
HttpUseAsyncIO booleano false Usar E/S HTTP assíncrona

Example:

HttpMaxTotalConnections=200;HttpMaxConnectionsPerRoute=100;HttpConnectionTimeoutInSeconds=60

Configuração de proxy

Defina as configurações de proxy HTTP e SOCKS para ambientes empresariais:

Parâmetro Tipo Padrão Description
UseProxy booleano false Habilitar proxy
ProxyTransport String http Tipo de transporte de proxy (http/tcp)
ProxyHost String None Nome do host do proxy
ProxyPort Integer None Porta de proxy
ProxyAuthEnabled booleano false Habilitar a autenticação de proxy
ProxyUsername String None Nome de usuário de autenticação de proxy
ProxyPassword String None Senha de autenticação de proxy
ProxyAuthScheme String basic Esquema de autenticação (Basic/Digest/NTLM)
ProxySocksVersion Integer 5 Versão do 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 log

Parâmetro Tipo Padrão Description
LogLevel String INFO Nível de log: TRACE, DEBUG, INFO, WARN, ERROR

Example:

LogLevel=DEBUG

Local de log padrão:

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

Configuração de log personalizada: Use um arquivo personalizado log4j2.xml ou logback.xml no seu 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();
        }
    }
}

Trabalhando 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
}

Usando instruçõ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 tipo de dados

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

Tipo SQL do Spark Tipo de SQL JDBC Tipo java Anotaçõ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