Partager via


Pilote Microsoft JDBC pour Microsoft Fabric Data Engineering (version préliminaire)

Note

Cette fonctionnalité est en préversion.

JDBC (Java Database Connectivity) est une norme largement adoptée qui permet aux applications clientes de se connecter et d’utiliser des données à partir de bases de données et de plateformes Big Data.

Microsoft JDBC Driver for Fabric Data Engineering vous permet de connecter, d’interroger et de gérer des charges de travail Spark dans Microsoft Fabric avec la fiabilité et la simplicité de la norme JDBC. Basé sur les API Livy de Microsoft Fabric, le pilote fournit une connectivité Spark SQL sécurisée et flexible à vos applications Java et outils BI. Cette intégration vous permet d’envoyer et d’exécuter du code Spark directement sans avoir à créer de notebook ou de définition de tâche Spark.

Principales fonctionnalités

  • Conforme JDBC 4.2 : implémentation complète de la spécification JDBC 4.2
  • Authentification d’ID Microsoft Entra : flux d’authentification multiples, notamment les informations d’identification interactives, les informations d’identification du client et l’authentification basée sur des certificats
  • Pool de connexions d’entreprise : pool de connexions intégré avec surveillance de l'état de santé et récupération automatique
  • Prise en charge des requêtes natives Spark SQL : exécution directe d’instructions Spark SQL sans traduction
  • Prise en charge complète des types de données : prise en charge de tous les types de données Spark SQL, y compris les types complexes (ARRAY, MAP, STRUCT)
  • Prérécupération asynchrone du jeu de résultats : chargement des données en arrière-plan pour améliorer les performances
  • Modèle disjoncteur : protection contre les défaillances en cascade avec nouvelle tentative automatique
  • Reconnexion automatique : récupération de session transparente sur les échecs de connexion
  • Prise en charge du proxy : configuration du proxy HTTP et SOCKS pour les environnements d’entreprise

Prerequisites

Avant d’utiliser Microsoft JDBC Driver for Microsoft Fabric Data Engineering, vérifiez que vous disposez des points suivants :

  • Kit de développement Java (JDK) : version 11 ou ultérieure (Java 21 recommandé)
  • Accès à Microsoft Fabric : accès à un espace de travail Microsoft Fabric
  • Informations d’identification d’ID Azure Entra : informations d’identification appropriées pour l’authentification
  • Identifiants d’espace de travail et de Lakehouse : identificateurs GUID pour votre espace de travail Fabric et votre Lakehouse.

Téléchargement et installation

Microsoft JDBC Driver pour Microsoft Fabric Data Engineering version 1.0.0 est la préversion publique et prend en charge Java 11, 17 et 21. Nous améliorons continuellement la prise en charge de la connectivité Java et vous recommandons d’utiliser la dernière version du pilote Microsoft JDBC.

  1. Téléchargez le fichier zip ou tar à partir des liens ci-dessus.
  2. Extrayez le fichier téléchargé pour accéder aux fichiers JAR du pilote.
  3. Sélectionnez le fichier JAR qui correspond à votre version JRE :
    • Pour Java 11 : ms-sparksql-jdbc-1.0.0.jre11.jar
    • Pour Java 17 : ms-sparksql-jdbc-1.0.0.jre17.jar
    • Pour Java 21 : ms-sparksql-jdbc-1.0.0.jre21.jar
  4. Ajoutez le fichier JAR sélectionné au chemin de classe de votre application.
  5. Pour les clients JDBC, configurez la classe de pilote JDBC : com.microsoft.spark.livy.jdbc.LivyDriver

Exemple de démarrage rapide

Cet exemple montre comment se connecter à Microsoft Fabric et exécuter une requête à l’aide du pilote Microsoft JDBC pour Microsoft Fabric Data Engineering. Avant d’exécuter ce code, vérifiez que vous avez rempli les prérequis et installé le pilote.

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

Format de chaîne de connexion

Chaîne de connexion de base

Microsoft JDBC Driver for Microsoft Fabric Data Engineering utilise le format de chaîne de connexion suivant :

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

Composants de chaîne de connexion

Composant Descriptif Example
Protocole Identificateur du protocole d’URL JDBC jdbc:fabricspark://
Nom d’hôte Nom d’hôte du point de terminaison Microsoft Fabric api.fabric.microsoft.com
Port Numéro de port facultatif (valeur par défaut : 443) :443
Paramètres Paires clé=valeur séparées par des points-virgules FabricWorkspaceID=<guid>

Exemples de chaînes de connexion

Connexion de base (authentification interactive)

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

Avec la configuration des ressources 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

Avec les propriétés de session 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

Microsoft JDBC Driver for Microsoft Fabric Data Engineering prend en charge plusieurs méthodes d’authentification via Microsoft Entra ID (anciennement Azure Active Directory). L’authentification est configurée à l’aide du AuthFlow paramètre dans la chaîne de connexion.

Flux d’authentification

AuthFlow Méthode d’authentification Cas d’usage
0 Informations d’identification Azure CLI Développement à l’aide d’Azure CLI
1 Informations d’identification du client (principal de service) Authentification automatisée/de service à service
2 Navigateur interactif Authentification utilisateur interactive (par défaut)
3 SPN Authentification du principal de service
4 À base de certificat Authentification d'un principal de service à l'aide d'un certificat
5 Jeton d'accès Jeton d’accès pré-acquis

Authentification interactive du navigateur

Idéal pour : Développement et applications interactives

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

Paramètres :

  • AuthFlow=2: spécifie l’authentification interactive du navigateur
  • AuthTenantID (facultatif) : ID de locataire Azure
  • AuthClientID (facultatif) : ID d’application (client)

Comportement:

  • Ouvre une fenêtre de navigateur pour l’authentification utilisateur
  • Les informations d’identification sont mises en cache pour les connexions suivantes jusqu’à ce qu’elles expirent
  • Adapté aux applications mono-utilisateur

Authentification des informations d’identification du client

Idéal pour : services automatisés et travaux en arrière-plan

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

Paramètres obligatoires :

  • AuthFlow=1: spécifie l’authentification des informations d’identification du client
  • AuthClientID: ID d’application (client) de Microsoft Entra ID
  • AuthClientSecret: Secret client de l'ID Microsoft Entra
  • AuthTenantID: ID de locataire Azure

Meilleures pratiques :

  • Stocker les secrets en toute sécurité (Azure Key Vault, variables d’environnement)
  • Utiliser des identités managées lorsque cela est possible
  • Changer régulièrement les secrets

Authentification par certificat

Idéal pour : les applications d’entreprise nécessitant une authentification basée sur des certificats

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

Paramètres obligatoires :

  • AuthFlow=4: spécifie l’authentification basée sur un certificat
  • AuthClientID: ID d’application (client)
  • AuthCertificatePath: chemin d’accès au fichier de certificat PFX/PKCS12
  • AuthCertificatePassword: Mot de passe du certificat
  • AuthTenantID: ID de locataire Azure

Authentification d’un principal de service

Idéal pour : environnements sans tête et sessions à distance

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

Comportement:

  • Affiche un code et une URL d’appareil dans la console
  • L’utilisateur visite l’URL et entre le code
  • L’authentification se termine après la vérification de l’utilisateur

Authentification par jeton d’accès

Idéal pour : scénarios d’authentification personnalisés

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

Mise en cache de l’authentification

Le pilote met automatiquement en cache les jetons d’authentification pour améliorer les performances :

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

Paramètres de configuration

Paramètres requis

Ces paramètres doivent être présents dans chaque chaîne de connexion :

Paramètre Type Descriptif Example
FabricWorkspaceID UUID (Identifiant Unique Universel) Identificateur de l’espace de travail Microsoft Fabric <workspace-id>
FabricLakehouseID UUID (Identifiant Unique Universel) Identificateur Microsoft Fabric Lakehouse <lakehouse-id>
AuthFlow Nombre entier Type de flux d’authentification (0-5) 2

Paramètres facultatifs

Configuration de la version de l’API

Paramètre Type Par défaut Descriptif
FabricVersion Chaîne v1 Version de l’API Microsoft Fabric
LivyApiVersion Chaîne 2023-12-01 Version de l’API Livy

Configuration de l’environnement

Paramètre Type Par défaut Descriptif
FabricEnvironmentID UUID (Identifiant Unique Universel) Aucun Identifiant de l'environnement "fabric" pour référencer un élément d'environnement dans une session Spark

Configuration de l’étincelle

Configuration des ressources de session

Configurez les ressources de session Spark pour des performances optimales :

Paramètre Type Par défaut Descriptif Example
DriverCores Nombre entier Spark par défaut Nombre de cœurs d’UC pour le pilote 4
DriverMemory Chaîne Spark par défaut Allocation de mémoire pour le pilote 4g
ExecutorCores Nombre entier Spark par défaut Nombre de cœurs de processeur par exécuteur 4
ExecutorMemory Chaîne Spark par défaut Allocation de mémoire par exécuteur 8g
NumExecutors Nombre entier Spark par défaut Nombre d’exécuteurs 2

Exemple :

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

Propriétés de session Spark personnalisées

Tout paramètre avec le préfixe spark. est automatiquement appliqué à la session Spark :

Exemples de configurations 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

Moteur d’exécution natif (NEE) :

spark.nee.enabled=true

Exemple complet :

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

Configuration du pool de connexions HTTP

Configurez le regroupement de connexions HTTP pour optimiser les performances réseau :

Paramètre Type Par défaut Descriptif
HttpMaxTotalConnections Nombre entier 100 Nombre maximal de connexions HTTP
HttpMaxConnectionsPerRoute Nombre entier 50 Nombre maximal de connexions par itinéraire
HttpConnectionTimeoutInSeconds Nombre entier 30 Délai d'attente de connexion
HttpSocketTimeoutInSeconds Nombre entier 60 Délai d'expiration de lecture du socket
HttpReadTimeoutInSeconds Nombre entier 60 Délai d’attente de lecture HTTP
HttpConnectionRequestTimeoutSeconds Nombre entier 30 Délai d’expiration de la demande de connexion à partir du pool
HttpEnableKeepAlive Booléen true Activer HTTP keep-alive
HttpKeepAliveTimeoutSeconds Nombre entier 60 Délai d’expiration de la durée de vie
HttpFollowRedirects Booléen true Suivre les redirections HTTP
HttpUseAsyncIO Booléen false Utiliser des E/S HTTP asynchrones

Exemple :

HttpMaxTotalConnections=200;HttpMaxConnectionsPerRoute=100;HttpConnectionTimeoutInSeconds=60

Configuration du serveur proxy

Configurez les paramètres de proxy HTTP et SOCKS pour les environnements d’entreprise :

Paramètre Type Par défaut Descriptif
UseProxy Booléen false Activer le proxy
ProxyTransport Chaîne http Type de transport proxy (http/tcp)
ProxyHost Chaîne Aucun Nom d’hôte du proxy
ProxyPort Nombre entier Aucun Port proxy
ProxyAuthEnabled Booléen false Activer l’authentification proxy
ProxyUsername Chaîne Aucun Nom d’utilisateur de l’authentification proxy
ProxyPassword Chaîne Aucun Mot de passe d’authentification proxy
ProxyAuthScheme Chaîne basic Schéma d’authentification (basic/digest/ntlm)
ProxySocksVersion Nombre entier 5 CHAUSSETTES version (4/5)

Exemple de proxy HTTP :

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

Exemple de proxy SOCKS :

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

Configuration de la journalisation

Paramètre Type Par défaut Descriptif
LogLevel Chaîne INFO Niveau de journalisation : TRACE, DEBUG, INFO, AVERTISSEMENT, ERROR

Exemple :

LogLevel=DEBUG

Emplacement du journal par défaut :

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

Configuration du journal personnalisé : Utilisez un fichier log4j2.xml ou logback.xml personnalisé dans votre classpath.


Exemples d’utilisation

Connexion de base

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

Exécution de requêtes

Requête simple

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

Requête avec filtre

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

Requête avec 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();
        }
    }
}

Utilisation des jeux de résultats

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

Traitement des jeux de résultats volumineux

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
}

Utilisation de requêtes préparées

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

Opérations de traitement par lots

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

Mappage de type de données

Le pilote mappe les types de données Spark SQL aux types JDBC SQL et java :

Type de Spark SQL JDBC SQL Type Java Type Remarques
BOOLEAN BOOLEAN Boolean
BYTE TINYINT Byte
SHORT SMALLINT Short
INT INTEGER Integer
LONG BIGINT Long
FLOAT FLOAT Float
DOUBLE DOUBLE Double
DECIMAL DECIMAL BigDecimal Précision et échelle conservées
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 Sérialisé en tant que JSON
MAP VARCHAR String Sérialisé en tant que JSON
STRUCT VARCHAR String Sérialisé en tant que JSON