Microsoft Fabric データ エンジニアリング用の Microsoft JDBC ドライバー

JDBC (Java Database Connectivity) は、クライアント アプリケーションがデータベースやビッグ データ プラットフォームのデータに接続して操作できるようにする、広く採用されている標準です。

Microsoft JDBC Driver for Fabric Data Engineeringは、JDBC標準の信頼性とシンプルさをもって、Fabric内でSparkワークロードを接続、照会、管理を可能にします。 FabricのLivy APIを基に構築されたこのドライバーは、JavaアプリケーションやBIツールに対して安全かつ柔軟なSpark SQL接続を提供します。 この統合により、別々のノートブックやSparkジョブ定義項目を作成することなく、Sparkコードを直接提出・実行できます。 このドライバーは、DbVisualizer や DBeaver などの一般的な JDBC クライアントや、Tableau などの JDBC 接続をサポートする BI ツールと互換性があります。

主な機能

  • JDBC 4.2 API:Spark SQL接続のためのJDBC 4.2 APIを実装しますが、JDBCトランザクションなしやフォワードのみ読み取り専用の結果セットなどのSparkおよびLivyの制限があります
  • Microsoft Entra ID 認証: 対話型、クライアント資格情報、証明書ベースの認証を含む複数の認証フロー
  • 高同時実行セッション: 同時実行ワークロード向けのオプトイン方式の Fabric セッション共有機能
  • 明示的な接続プーリング:標準的なプールマネージャーであるHikariCP、または LivyBuiltInPooledDataSourceを選択し、直接のエントリーポイントはプールしません
  • Spark SQLネイティブクエリサポート:変換なしでSpark SQL文を直接実行
  • 包括的なデータ型のサポート: 複合型 (ARRAY、MAP、STRUCT) を含むすべての Spark SQL データ型のサポート
  • 非同期の結果セットプリフェッチ: パフォーマンス向上のためのバックグラウンド データ読み込み
  • サーキット ブレーカー パターン: 自動再試行による連鎖障害に対する保護
  • 自動再接続: 接続エラー時の透過的なセッション復旧
  • 高度な再試行ロジック: 指数バックオフとセッション回復を使用して再試行し、回復性を向上させる
  • プロキシのサポート: エンタープライズ環境向けの HTTP および SOCKS プロキシの構成

[前提条件]

Microsoft JDBCドライバー for Fabric Data Engineeringを使用する前に、以下の点を確認してください:

  • Java開発キット(JDK):Java 11、17、21(Java 21推奨)
  • Fabricアクセス:Fabricワークスペースへのアクセス
  • Microsoft Entra ID資格情報: 認証に適した資格情報
  • ワークスペース ID とレイクハウス ID: Fabric ワークスペースとレイクハウスの GUID 識別子

ダウンロードとインストール

Microsoft JDBCドライバー for Fabric Data Engineering バージョン2.0.1はJava 11、17、21をサポートしています。 使用可能な最新バージョンを使用します。

  1. 上記のリンクから zip または tar ファイルをダウンロードします。
  2. ダウンロードしたファイルを抽出して、ドライバー JAR ファイルにアクセスします。
  3. JRE バージョンに一致する JAR ファイルを選択します。
    • Java 11 の場合: ms-sparksql-jdbc-2.0.1.jre11.jar
    • Java 17 の場合: ms-sparksql-jdbc-2.0.1.jre17.jar
    • Java 21 の場合: ms-sparksql-jdbc-2.0.1.jre21.jar
  4. 選択した JAR ファイルをアプリケーションのクラスパスに追加します。
  5. JDBC クライアントの場合は、JDBC ドライバー クラスを構成します。 com.microsoft.spark.livy.jdbc.LivyDriver

クイック スタートの例

この例は、Microsoft JDBCドライバー for Fabric Data Engineeringを使って、Fabricに接続しクエリを実行する方法を示しています。 このコードを実行する前に、前提条件を満たし、ドライバーをインストールしてください。 AuthFlow=2を使うことで、運転手はDefaultAzureCredentialを使います。 Azure CLIを認証情報ソースとして使うには、Azure CLIをインストールしてaz loginを実行します。

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;" +  // DefaultAzureCredential; Azure CLI can be one source
                     "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();
        }
    }
}

接続文字列の形式

基本的な接続文字列

Microsoft JDBCのFabricデータエンジニアリングドライバーは、以下の接続文字列形式を使用しています:

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

接続文字列コンポーネント

コンポーネント Description Example
プロトコル JDBC URL プロトコル識別子 jdbc:fabricspark://
ホスト名 Fabric エンドポイント ホスト名 api.fabric.microsoft.com
ポート オプションのポート番号 (既定値: 443) :443
パラメーター セミコロンで区切られたキーと値のペア FabricWorkspaceID=<guid>

接続文字列の例

基本接続 (対話型ブラウザー ベースの認証)

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

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

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

高並行モード

高並行性(HC)モードは、ドライバーバージョン1.1.0以降のMicrosoft Fabric接続で利用可能です。 hcEnabled=trueを加えて、古典的なリウィウスのセッションではなくHCセッションを取得できます:

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

オプションでセッションタグでワークロードを特定し、Fabric環境を選択することもできます:

jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=2;hcEnabled=true;sessionTag=orders_etl;FabricEnvironmentID=<environment-id>

HCモードはオプトイン制です。 hcEnabledが省略またはfalseに設定されている場合、ドライバーはクラシックなLivyセッションパスを使用します。

完全な設定ガイダンスについては 「High-Concurrency(HC)モード 」セクションを参照してください。


Authentication

Microsoft JDBCドライバー for Fabric Data Engineeringは、Microsoft Entra ID(旧Azure Active Directory)を通じて複数の認証方法をサポートしています。 認証は、接続文字列の AuthFlow パラメーターを使用して構成されます。

認証フロー

AuthFlow 認証方法 使用事例
1 対話型ブラウザー OAuth 2.0 を使用した対話型ユーザー認証
2 既定の Azure 資格情報チェーン 開発および管理されたアプリケーション認証;Azure CLIは1つの認証情報ソースとなり得ます
3 クライアント シークレット資格情報 (サービス プリンシパル) 自動/サービス間認証
4 クライアント証明書の資格情報 証明書ベースのサービス プリンシパル認証
5 アクセストークン 事前に取得されたベアラー アクセス トークン

対話型ブラウザー認証

最適な用途: 開発と対話型アプリケーション

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=1;" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

パラメーター:

  • AuthFlow=1: 対話型ブラウザー認証を指定します

動作:

  • ユーザー認証用のブラウザー ウィンドウを開きます
  • その後の接続のために認証情報をキャッシュし、期限切れまで保存します
  • シングル ユーザー アプリケーションに適しています

クライアント資格情報またはサービス プリンシパル認証

最適な用途は: 自動化されたサービスとバックグラウンド ジョブ

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

Connection conn = DriverManager.getConnection(url);

必須パラメーター:

  • AuthFlow=3: クライアント資格情報認証を指定します
  • AuthClientID: Microsoft Entra ID からのアプリケーション (クライアント) ID
  • AuthClientSecret: Microsoft Entra ID からのクライアント シークレット
  • AuthTenantID: Microsoft Entra テナント ID

ベスト プラクティス:

  • シークレットを安全に格納する (Azure Key Vault、環境変数)
  • 可能な場合はマネージド ID を使用する
  • シークレットを定期的にローテーションする

証明書ベースの認証

最適な対象: 証明書ベースの認証を必要とするエンタープライズ アプリケーション

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

Connection conn = DriverManager.getConnection(url);

必須パラメーター:

  • AuthFlow=4: 証明書ベースの認証を指定します
  • AuthClientID: アプリケーション (クライアント) ID
  • AuthCertificatePath: PEM証明書ファイルへのパス
  • AuthCertificatePassword: 証明書パスワード
  • AuthTenantID: Microsoft Entra テナント ID

アクセス トークン認証

最適な用途: カスタム認証シナリオ

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

認証キャッシュ

ドライバーは認証トークンをキャッシュし、トークンの有効期限に応じて更新します。 解析された AuthEnableCaching と AuthCacheTTLMS プロパティはバージョン2.0.0ではこの動作を制御しません。

構成パラメーター

必須のパラメーター

これらのパラメーターは、すべての接続文字列に存在する必要があります。

パラメーター タイプ Description Example
FabricWorkspaceID UUID(ユニバーサリー・ユニーク・アイデンティファイア) ファブリック ワークスペース識別子 <workspace-id>
FabricLakehouseID UUID(ユニバーサリー・ユニーク・アイデンティファイア) Fabric Lakehouse 識別子 <lakehouse-id>
AuthFlow 整数 認証フローの種類 (1 から 5) 2

省略可能なパラメーター

API バージョンの構成

パラメーター タイプ 既定値 Description
FabricVersion 糸 v1 Fabric APIバージョン
LivyApiVersion 糸 2023-12-01 Livy API バージョン

環境の構成

パラメーター タイプ 既定値 Description
FabricEnvironmentID UUID(ユニバーサリー・ユニーク・アイデンティファイア) None Spark セッションの環境項目を参照するためのファブリック環境識別子

高並行セッション構成

hcEnabled=trueをHCモードに設定してください。 残りのHCプロパティはHCモードが有効化された場合にのみ使用されます。

パラメーター タイプ 既定値 Description
hcEnabled ブール値 false Fabricの高並行実行セッションを使用しています。
sessionTag 糸 None オプションのサーバーサイドセッションタグ。 1から64までの文字、数字、アンダースコア、またはハイフンを使いましょう。
hcAcquireTimeoutSeconds 整数 300 HCセッションが準備完了するまで最大待機時間。 有効な時間は120秒から3,600秒の範囲です。
hcAcquirePollingIntervalMs 整数 1000 HCセッションのステータスチェック間隔。 許容される値は50から30,000ミリ秒の範囲で、実行時に100から5,000ミリ秒までクランプされます。

Example:

hcEnabled=true;sessionTag=interactive_reporting;hcAcquireTimeoutSeconds=600;hcAcquirePollingIntervalMs=2000;FabricEnvironmentID=<environment-id>
  • FabricEnvironmentID HCセッションとクラシックセッションの両方に適用されます
  • EnvironmentID また、クロスドライバーの別名としても受け入れられています。 プロパティ名では大文字と小文字が区別されません。

Important

sessionTagは非機密の操作ラベルにのみ使用してください。 秘密情報、アクセストークン、個人データ、顧客識別子、クエリテキストは含めないでください。

完全な設定ガイダンスについては 「High-Concurrency(HC)モード 」セクションを参照してください。

Spark 構成

セッション リソースの構成

最適なパフォーマンスを得られるように Spark セッション リソースを構成します。

パラメーター タイプ 既定値 Description Example
DriverCores 整数 Spark の既定値 ドライバーの CPU コア数 4
DriverMemory 糸 Spark の既定値 ドライバーのメモリ割り当て 4g
ExecutorCores 整数 Spark の既定値 Executor あたりの CPU コア数 4
ExecutorMemory 糸 Spark の既定値 Executor あたりのメモリ割り当て 8g
NumExecutors 整数 Spark の既定値 Executor の数 2
SessionName 糸 自動生成 カスタムセッション名 MySparkSession

Example:

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

カスタム Spark セッションのプロパティ

プレフィックス spark. を持つパラメーターは、Spark セッションに自動的に適用されます。

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

spark.nee.enabled=true

完全な例:

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

HTTPクライアント接続設定

最適なネットワーク性能のためにドライバーのHTTPトランスポート接続を設定してください。 これらの設定はJDBC接続プーリングの設定や管理にはなりません:

パラメーター タイプ 既定値 Description
HttpMaxTotalConnections 整数 100 HTTP 接続の最大数
HttpMaxConnectionsPerRoute 整数 20 ルートあたりの最大接続数
HttpConnectionTimeoutInSeconds 整数 30 接続タイムアウト
HttpSocketTimeoutInSeconds 整数 60 ソケットの読み取りタイムアウト
HttpReadTimeoutInSeconds 整数 60 HTTP 読み取りタイムアウト
HttpConnectionRequestTimeoutSeconds 整数 10 プールからの接続要求のタイムアウト
HttpEnableKeepAlive ブール値 true HTTP キープアライブを有効にする
HttpKeepAliveTimeoutSeconds 整数 60 キープアライブ タイムアウト
HttpFollowRedirects ブール値 true HTTP リダイレクトに従う
HttpUseAsyncIO ブール値 true 非同期 HTTP I/O を使用する

Example:

HttpMaxTotalConnections=200;HttpMaxConnectionsPerRoute=100;HttpConnectionTimeoutInSeconds=60

プロキシの構成

エンタープライズ環境の HTTP および SOCKS プロキシ設定を構成します。

パラメーター タイプ 既定値 Description
UseProxy ブール値 false プロキシを有効にする
ProxyTransport 糸 http プロキシ トランスポートの種類 (http/tcp)
ProxyHost 糸 None プロキシホスト名
ProxyPort 整数 None プロキシ ポート
ProxyAuthEnabled ブール値 false プロキシ認証を有効にする
ProxyUsername 糸 None プロキシ認証のユーザー名
ProxyPassword 糸 None プロキシ認証パスワード
ProxyAuthScheme 糸 basic 認証スキーム (basic/digest/ntlm)
ProxySocksVersion 整数 5 SOCKS バージョン (4/5)

HTTP プロキシの例:

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

SOCKS プロキシの例:

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

ログ記録の構成

パラメーター タイプ 既定値 Description
LogLevel 糸 WARN ログ レベル: TRACE、DEBUG、INFO、WARN、ERROR

Example:

LogLevel=DEBUG

既定のログの場所:

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

カスタム ログ構成: クラスパスでカスタム log4j2.xml または logback.xml ファイルを使用します。

高並行性(HC)モード

ハイコンカレンシー(HC)モードは、同じFabricワークスペースおよびレイクハウスに複数の接続を開くJDBCアプリケーション向けに設計されています。 Fabricは、すべての接続ごとに別々のクラシックSparkセッションをプロビジョニングするのではなく、サーバー管理のSpark容量でそれらの接続を提供しています。

HCモードは接続開始時間を短縮し、Sparkセッションの繰り返すプロビジョニングを避け、同時処理の処理で利用可能な容量をより効率的に利用できます。 各JDBC接続は、HCセッション内で割り当てられたコンテキストを通じて文の実行を続けます。

HCモードはオプトイン方式で、JDBC接続プーリングを補完します。 HCモードはサーバー上のFabric Sparkセッションを管理し、JDBC接続プーリングはクライアントアプリケーション内の接続を管理します。 HCモードを有効にしない場合、ドライバーはクラシックなLivyセッションを作成します。

ハードコアモードとクラシックモードのどちらかを選べます

HCモードを使う場合:

  • アプリケーションサービスは、複数のJDBC接続を通じてSpark SQLを実行する同時リクエストを処理します。
  • BIやレポーティングツールは、同じワークスペースやレイクハウスへの複数の接続を開放します。
  • 並列のETLタスクやスケジュールされたジョブは、JDBC接続のバーストを生み出します。
  • 接続は互換性のあるSpark構成を使用し、サーバー管理のSpark容量を共有できます。
  • 接続開始時間の短縮とSparkセッションの繰り返されるプロビジョニングが重要です。

クラシックモードを使う場合:

  • あなたのアプリケーションは、長期間使われているJDBC接続を1つか数つだけ使っています。
  • 各接続には、厳密なワークロードやリソース隔離のために専用のSparkセッションが必要です。
  • 接続は大きく異なるSpark構成やFabric環境を必要とします。
  • ターゲットワークスペースとレイクハウス用のFabric LivyエンドポイントはHCモードをサポートしていません。

高並行性モードを有効にする

HCモードはオプトイン制です。 hcEnabledを省略したりfalseに設定した場合、ドライバーはクラシックなLivyセッションパスを使用します。 hcEnabledをtrueに設定してHCセッションを取得してください:

hcEnabled=true;

HCモードでの必要なパラメータ

HCの有効化には以下の有効な識別子が必要です:

パラメーター 注記
WorkspaceId 有効なFabricワークスペースのGUIDでなければなりません。
LakehouseId 有効な Fabric レイクハウスの GUID である必要があります。

ウォームセッションのサーバーサイドマッチングに影響を与えるため SessionTag 含めてください。

セッションマッチング

HCモードはすべての接続が既存のセッションを再利用することを保証するわけではありません。 各セッション取得リクエストに対して、ドライバーは以下を送信します:

  • SessionTag の値。
  • 効果的なSpark構成、 conf.* 設定や EnvironmentIdが含まれます。

Fabric Livyサービスはこれらの値を評価し、接続をウォームセッションに付けるか新しいセッションを作成するかを決定します。 セッションの再利用を改善するために、サーバー管理のSpark容量を共有することを意図した接続間で一貫した値を使いましょう。

HCモードを無効にしてください

新しい HC セッション取得を無効化するには、ドライバーを再デプロイせずに済みます。HC 接続文字列 を false に設定するか、HC パラメータを削除することで可能です:

hcEnabled=false;

緊急ロールバック: 緊急ロールバックの場合は、JVMを -Dcom.microsoft.fabric.jdbc.hc.disable=trueで起動してください。 このJVM全体のスイッチは、接続文字列にhcEnabled=trueが含まれている場合でもクラシックモードを強制します。

HCのランタイム動作を理解する

  • HCのセッション取得は、セッションが準備完了するか hcAcquireTimeoutSeconds 期限が切れるまでブロックされます。
  • 取得処理の実行中に接続を閉じると、取得が中断され、HC セッションのクリーンアップがベストエフォートで実行されます。
  • 認証、クエリ実行、キャンセル、準備文、結果処理、 FabricEnvironmentID は両モードで標準のJDBCインターフェースを通じて動作します。

使用例

基本接続

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

高並行モード接続

以下の例は、HCモードでJDBC接続を開き、クエリを実行し、自動的に接続を解放します。

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=2;" +
             "hcEnabled=true;" +
             "sessionTag=dashboard_queries;" +
             "FabricEnvironmentID=<environment-id>";

try (Connection conn = DriverManager.getConnection(url);
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery("SELECT current_timestamp()")) {
    while (rs.next()) {
        System.out.println(rs.getTimestamp(1));
    }
}

クエリの実行

単純なクエリ

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

フィルターを使用したクエリ

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

制限付きクエリ

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

結果セットの操作

トラバース結果集合

public void navigateResultSet(Connection conn) throws SQLException {
    String sql = "SELECT id, name, amount FROM orders";
    
    try (Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(sql)) {

        while (rs.next()) {
            System.out.printf(
                "Order %d: %s, %.2f%n",
                rs.getInt("id"),
                rs.getString("name"),
                rs.getDouble("amount"));
        }
    }
}

結果セットは前方向専用であり、読み取り専用です。 ドライバーは first()、 last()、 absolute()といったメソッドをサポートしていません。

大規模な結果セットの処理

ドライバーは応答サイズで結果をページ化します。 JDBC URLの LivyStatementPageSize を設定し、リクエストされたページサイズをバイト単位で設定します。 Statement.setFetchSize()メソッドは検索やメモリ使用を制御しません。

jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=2;LivyStatementPageSize=1048576
public void processLargeResultSet(Connection conn) throws SQLException {
    String sql = "SELECT * FROM large_table";
    
    try (Statement stmt = conn.createStatement()) {
        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
}

準備されたステートメントの使用

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

バッチ操作

このドライバーはJDBC取引をサポートしていません。 バッチ実行は非トランザクション的であり、部分的に成功することもあります。 後の失敗は、以前の成功した発言を後退させるものではありません。

public void executeBatchInsert(Connection conn) throws SQLException {
    String sql = "INSERT INTO logs (timestamp, level, message) VALUES (?, ?, ?)";
    int pendingStatements = 0;
    
    try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        // 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();
            pendingStatements++;
            
            // Execute batch every 100 statements
            if ((i + 1) % 100 == 0) {
                pstmt.executeBatch();
                pstmt.clearBatch();
                pendingStatements = 0;
            }
        }
        
        if (pendingStatements > 0) {
            pstmt.executeBatch();
        }
        
        System.out.println("Batch insert completed successfully");
    }
}

接続所有者を選ぶ

接続ライフサイクルを所有するコンポーネントを1つ選びます。 一つの接続プールを別のプールに配置しないでください。

使用モデル 入り口ポイント プールのオーナー 借り物を閉じる Connection 閉鎖オーナー
直接 DriverManager、 LivyDriver、または LivyDataSource None 独立した Livy への接続とセッションを実際に閉じます。 アプリケーションはすべての接続を閉じます。 直接の LivyDataSource には密接なライフサイクルが存在しません。
外部のHikariCP HikariDataSource JDBCのURLを裏付ける、または LivyDataSource HikariCPのみ Hikariプロキシ接続をHikariCPに返します。 アプリケーションは保持しているHikariDataSourceを閉じます。
明示的な組み込みプール LivyBuiltInPooledDataSource 各設定されたデータソース生成ごとに、怠惰に作成された1つの LivyConnectionPool 論理リースを廃止し、安全なクリーンアップ後にのみ物理セッションを再利用します。 アプリケーションは保持された組み込みデータソースを閉じます。
標準プーリング SPI LivyConnectionPoolDataSource 中間層のプールマネージャーのために PooledConnection オブジェクトを作成します 中堅のプールマネージャーであって、工場ではありません 論理ハンドルを閉じ、クリーンアップ後に同期的にマネージャーに通知します。 マネージャーは PooledConnection.close() に連絡して、すべての物理的な接続を切断する。

ConnectionPoolEnabled は、ドライバーコードと出荷時のプロパティの両方で、デフォルトでは false になります。 これは現在のエントリーポイント向けのオプトイン用スイッチではありません。 ドライバがプールを所有すべき LivyBuiltInPooledDataSource を使うか、HikariCPのような外部プールを設定しましょう。 他のエントリーポイントは直接的でプールを所有しない接続を形成します。

HikariCPを使用した接続プーリング

HikariCPは LivyDataSource またはJDBCのURLから LivyDriverを通じて接続を作成できます。 HikariCPインスタンスを1つ作成し、アプリケーションの寿命に合わせて再利用し、どちらの設定でも接続プールは1つだけ使用します。

Maven の依存関係

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.1</version>
</dependency>

LivyDataSource を使用する

LivyDataSource 独立した物理接続を作成し、接続プールやクローズドライフサイクルを所有しません。 直接HikariCPに供給し、HikariCPが唯一のプール所有者となるようにしてください:

import com.microsoft.spark.livy.jdbc.LivyDataSource;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public final class ConnectionPoolExample implements AutoCloseable {
    private final HikariDataSource hikariDataSource;

    public ConnectionPoolExample(String url) {
        LivyDataSource configuredDataSource = new LivyDataSource();
        configuredDataSource.setUrl(url);

        HikariConfig config = new HikariConfig();
        config.setDataSource(configuredDataSource);
        config.setMaximumPoolSize(2);
        config.setMinimumIdle(0);
        config.setConnectionTimeout(900000);     // Wait up to 15 minutes for a connection
        config.setInitializationFailTimeout(-1); // Connect on demand
        config.setIdleTimeout(600000);           // 10 minutes
        config.setMaxLifetime(1800000);          // 30 minutes
        config.setPoolName("FabricSparkPool");

        hikariDataSource = new HikariDataSource(config);
    }

    public Connection getConnection() throws SQLException {
        return hikariDataSource.getConnection();
    }

    @Override
    public void close() {
        hikariDataSource.close();
    }

    public static void main(String[] args) throws SQLException {
        String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
                     "FabricWorkspaceID=<workspace-id>;" +
                     "FabricLakehouseID=<lakehouse-id>;" +
                     "AuthFlow=AZURE_CLI;" +
                     "hcEnabled=true;" +
                     "sessionTag=pooled_app;" +
                     "hcAcquireTimeoutSeconds=600";

        try (ConnectionPoolExample pool = new ConnectionPoolExample(url);
             Connection conn = pool.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT 'Pooled connection!' as message")) {

            if (rs.next()) {
                System.out.println(rs.getString("message"));
            }
        }
    }
}

この例はJDBCのURLでHCモードを有効にしています。 HikariCPはクライアント側の接続を管理し、HCモードはFabric内の共有Sparkセッションを管理します。 アプリケーションがクラシックセッションを必要とする場合は hcEnabled を削除し sessionTag してください。

LivyDriverを直接使用する

JDBCのURLとドライバークラスを設定し、HikariCPが LivyDriverを通じて物理的な接続を作成できるようにします。 JDBCサービスプロバイダーの自動検出機能がある場合、ドライバークラスの明示的な設定は任意です。 この構成では LivyDataSourceをインスタンス化しないため、内蔵プールは関与しません:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public final class DriverConnectionPoolExample {
    public static HikariDataSource createPool(String url) {
        HikariConfig config = new HikariConfig();
        config.setDriverClassName("com.microsoft.spark.livy.jdbc.LivyDriver");
        config.setJdbcUrl(url);

        // Keep pool sizes small: each classic-mode physical connection owns a Livy session.
        config.setMaximumPoolSize(2);
        config.setMinimumIdle(0);
        config.setConnectionTimeout(900000);     // Wait up to 15 minutes to borrow a connection
        config.setInitializationFailTimeout(-1); // Skip startup validation; connect on demand
        config.setIdleTimeout(600000);           // 10 minutes
        config.setMaxLifetime(1800000);          // 30 minutes
        config.setPoolName("FabricSparkDriverPool");

        return new HikariDataSource(config);
    }

    public static void main(String[] args) throws SQLException {
        String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
                     "FabricWorkspaceID=<workspace-id>;" +
                     "FabricLakehouseID=<lakehouse-id>;" +
                     "AuthFlow=AZURE_CLI;" +            // Uses the DefaultAzureCredential chain
                     "hcEnabled=true;" +
                     "sessionTag=pooled_app;" +
                     "hcAcquireTimeoutSeconds=600";  // Poll up to 10 minutes for HC readiness

        // Reuse this pool for the application lifetime; main closes it at process exit.
        try (HikariDataSource pool = createPool(url);
             Connection conn = pool.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT 'Pooled LivyDriver connection!' as message")) {

            if (rs.next()) {
                System.out.println(rs.getString("message"));
            }
        }
    }
}

プールを設定する際は以下のガイダンスを参考にしてください:

設定または挙動 Guidance
プールの所有権 LivyDataSource は直接接続のみです。 HikariCPに供給すると、HikariCPがプールの所有者になります。 ドライバーがプールを所有する必要がある場合は、代わりに LivyBuiltInPooledDataSource を使用してください。
プール サイズ まずは小さなプールから始め、ワークロードの並行性と容量使用量を測定してから拡大します。 クラシックモードでは、各物理接続がリウィスセッションを所有します。 HCモードでは、接続がサーバー管理のSpark容量を共有できます。
connectionTimeout 通話者が回線を借りるまでの待ち時間を制御しますが、すでに進行中の接続試行をキャンセルすることはありません。 HCのURLでは hcAcquireTimeoutSecondsを許可し、クラシックモードでは LivySessionTimeoutSeconds、認証、HTTPリトライ、検証を許可します。 HikariCPはこの設定をミリ秒単位で表現します。
initializationFailTimeout マイナス値は起動接続と検証試行をスキップします。 接続障害はアプリケーションが最初に接続を要求したときに表面化します。 起動時に接続性を確認する必要がある場合は正の値を使いましょう。
接続検証 HikariCPは Connection.isValid()を使用しています。 有効持続時間はHikariCPの validationTimeoutではなく、ドライバーのHTTPタイムアウトおよび再試行・バックオフ設定によって制御されます。 接続テストクエリを設定しないでください。なぜなら、それは軽い検証チェックをSpark文に置き換えるからです。

HikariCPの設定オプションの完全なリストについては、以下をご覧ください:

データ型マッピング

ドライバーは、Spark SQL データ型を JDBC SQL 型と Java 型にマップします。

Spark SQL の種類 JDBC SQL 型 Java 型 注記
BOOLEAN BOOLEAN Boolean
BYTE TINYINT Byte
SHORT SMALLINT Short
INT INTEGER Integer
LONG BIGINT Long
FLOAT FLOAT Float
DOUBLE DOUBLE Double
DECIMAL DECIMAL BigDecimal 精度とスケールの保持
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 ARRAY String JSONテキストとして取得されます。メタデータタイプは完全な java.sql.Array アクセスサポートを保証するものではありません
MAP JAVA_OBJECT String JSONテキストとして取得
STRUCT STRUCT String JSONテキストとして取得されます。メタデータタイプは完全な java.sql.Struct アクセスサポートを保証するものではありません