快速入門:使用 Java 和 Maven 連接 SQL Server

使用 Microsoft SQL Server 的 Java 資料庫連線 (JDBC) 驅動程式,讓 Java 應用程式連線至 SQL Server、Azure SQL Database 或 Fabric 中的 SQL 資料庫。 此快速入門軟體使用 Maven 下載相依性、讀取環境變數中的連線設定,並驗證參數化查詢結果。 你不需要 AdventureWorks 或任何範例表格。

對於 Azure SQL Database 或 Fabric 中的 SQL 資料庫,請使用 Microsoft Entra ID 認證,且不在應用程式中儲存密碼。 在本地開發期間,請透過瀏覽器登入。 對於在 Azure 中託管的應用程式,請使用受管理身份。

Prerequisites

  • Java 開發套件(JDK)21. 請使用 java -version 檢查您的安裝。
  • Apache Maven。 執行 mvn -version,並確認 Maven 使用的是 JDK 21。
  • 資料庫和連線權限。 在「選擇你的資料庫」中選擇託管資料庫或 SQL Server 容器。 查詢讀取的是計算出來的值,並不會建立或修改資料庫物件。
  • 網路存取你的資料庫端點。 針對 Azure SQL,設定網路存取。 若為 Fabric,請依照 連線到您的 SQL 資料庫。 對於 SQL Server,啟用傳輸控制協定/網際網路協定(TCP/IP)並使用已設定的埠。
  • 一個伺服器憑證,你的 Java 執行時會信任它。 應用程式需要加密並驗證伺服器憑證。 對於私有憑證授權單位,請參閱 信任私有憑證授權單位。

選擇您的資料庫

使用現有資料庫,或依照以下指南建立資料庫。 一個空的資料庫就足夠了。

Database 設定與存取
Fabric 中的 SQL 資料庫 建立 SQL 資料庫,然後遵守 Fabric 的認證與存取要求。 從 設定>的連線字串複製資料庫的伺服器名稱和資料庫名稱。 使用 SQL 資料庫連線,而非其 SQL 分析端點。
Azure SQL Database 建立單一資料庫。 請您的系統管理員設定 Microsoft Entra 管理員,並為您的身分識別建立資料庫使用者。 僅有 Azure 訂閱存取權,並不會授予資料庫存取權。
SQL Server 容器 可使用 Docker、sqlcmd 或 Visual Studio Code 的 MSSQL 擴充功能建立容器。 使用容器主機的 DNS 名稱、已發佈的 TCP 連接埠,以及具有連線到您的資料庫權限的 SQL 登入帳戶。
現有 SQL Server 使用實例的 DNS 名稱、TCP 埠口和現有的資料庫。 請向你的管理員申請 SQL 登入並取得連線權限。

SQL Server Linux 容器映像需要支援的 x86-64 主機。 在 ARM64 開發電腦上,將此 Java 應用程式運行於託管資料庫或支援遠端主機的容器,而非依賴容器模擬。

新容器可能會使用你的 JDK 不信任的憑證。 在執行此範例前,先設定伺服器憑證,並為私人發行者設定 Java 信任儲存庫。 容器連線時也要啟用憑證驗證功能。

創建 Maven 專案

創建名為 jdbc-quickstart的目錄。 在該目錄中,請建立 pom.xml,內容如下。 Maven 會管理類別路徑;你不需要手動下載 Java 壓縮檔(JAR)。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>jdbc-quickstart</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.release>21</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>13.6.0.jre11</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-core-http-netty</artifactId>
            <version>1.16.6</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity</artifactId>
            <version>1.18.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.14.0</version>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.5.0</version>
                <configuration>
                    <executable>${java.home}/bin/java</executable>
                    <arguments>
                        <argument>-classpath</argument>
                        <classpath />
                        <argument>Quickstart</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

jre11 驅動程式構件與 JDK 21 相容。 明確指定的 azure-identity 相依性會提供此快速入門中 Microsoft Entra 模式所需的驗證程式庫;這些程式庫是驅動程式的選用相依性,不會自動新增至您的應用程式。

這些版本與 已發佈的 JDBC 13.6.0 Maven 專案物件模型(POM)相符。 明確 azure-core-http-netty 相依性保留該驅動程式釋出所選擇的傳輸版本。

關於驅動程式更新,請查看下載頁面、已發佈的 Maven 版本以及 Java 支援矩陣。 更新驅動程式時,請將認證依賴與驅動程式公布的 POM 相符。 參見 特徵相依關係。 使用明確的發佈版本,而非 Maven 版本範圍或 LATEST。

設定連線

在你執行 Maven 的同一個終端機裡設定環境變數。 用你的端點和資料庫名稱替換 <server> 和 <database> 。 僅設定 SQL_SERVER_NAME 主機名稱,不包含 JDBC URL 或埠碼。

若複製的伺服器值為 tcp:<server>,1433,則僅將 <server> 用於 SQL_SERVER_NAME,並將 SQL_PORT 設為 1433。 主機名稱中不要包含 tcp: 前綴或 ,1433 後綴。

Azure SQL 或 Fabric 搭配 Microsoft Entra 驗證

在地開發時,請使用 ActiveDirectoryInteractive。 驅動程式會開啟瀏覽器登入,並支援多重驗證。 請用有權限存取資料庫的身份登入。 不要設定 SQL_USER 或 SQL_PASSWORD 為此模式。

對於 Azure SQL Database,請將主機名稱替換<server>為完整的主機名稱,例如 contoso.database.windows.net。 對於 Fabric,請從 SQL 資料庫的連線設定複製主機名稱;不要從資料庫名稱構造主機名稱,也不要加上 Azure SQL 後綴。 Fabric 需要 Microsoft Entra 認證;不要使用 Fabric 的 SQL 認證範例。

$env:SQL_SERVER_NAME = "<server>"
$env:SQL_DATABASE_NAME = "<database>"
$env:SQL_PORT = "1433"
$env:SQL_AUTHENTICATION = "ActiveDirectoryInteractive"

對於託管於 Azure 資源、系統指派管理身份的無頭應用程式:

  1. 啟用資源的受控識別。
  2. 請要求您的管理員授與該身分資料庫的存取權限。 對於 Azure SQL,請為該身份建立一個資料庫使用者。 對於 Fabric,請遵循 Fabric 的認證與存取要求,包括服務主體適用的租戶設定。
  3. 在主機的應用程式設定中設定SQL_AUTHENTICATION為 。ActiveDirectoryManagedIdentity 保留伺服器、資料庫和埠口設定。 同一個 Java 應用程式在沒有瀏覽器或密碼的情況下執行。

管理身份需要支援的 Azure 主機;它不能取代你工作站上的互動式登入。 關於使用者指派身份及其他認證模式,請參見使用 Microsoft Entra 認證的連接方式。

SQL Server 與 SQL 認證

對於 SQL Server 容器或已設定為 SQL 驗證的現有執行個體,請將 SQL_AUTHENTICATION 設為 SqlPassword,並提供可存取您資料庫的 SQL 登入帳戶。 此範例請勿使用伺服器管理員帳號。 PowerShell 密碼提示字元需要 PowerShell 7.1 或更新版本。

$env:SQL_SERVER_NAME = "<server>"
$env:SQL_DATABASE_NAME = "<database>"
$env:SQL_PORT = "1433"
$env:SQL_AUTHENTICATION = "SqlPassword"
$env:SQL_USER = "<user_id>"
$env:SQL_PASSWORD = Read-Host "SQL password" -MaskInput

如果不是 1433,請使用你實例的 TCP 埠。 環境變數會讓憑證不會出現在原始碼裡,但它們不是秘密儲存庫。 不要把它們記錄下來,也不要提交到原始碼控制。 在設定密碼變數時,不要啟用 Maven 除錯日誌-X(),執行外掛會記錄子程序的環境值。 對於已部署的應用程式,請使用你平台的秘密管理與 安全連線設定。

信任私人憑證授權中心

如果你的 JDK 已經信任伺服器的憑證發行者,可以跳過這部分。 否則,請透過可信管道從管理員取得發行憑證授權機構(CA)的公開憑證及 SHA-256 指紋。 不要因為伺服器在連線失敗時顯示憑證就相信它。

設定 SQL_SERVER_NAME 為伺服器憑證涵蓋且可由電腦解析的 DNS 名稱。 應用程式不會覆寫 hostNameInCertificate,所以驅動程式會驗證已設定的伺服器名稱。 新增受信任的 CA 並不能解決憑證名稱不符的問題。

使用 Maven 所使用的同一個 JDK 21 安裝中的 keytool。 用已驗證的 CA 憑證路徑、<jdk-home>該 JDK 的目錄,以及<trust-store-file>專案外的新絕對路徑取代<ca-certificate-file>。 將信任儲存放在其他非特權使用者無法修改的目錄中。 如果有任何指令失敗就停止。

  1. 檢查加州憑證,並將其 SHA-256 指紋與管理員提供的數值做比較。

    keytool -printcert -file "<ca-certificate-file>"
    
  2. 透過複製 JDK 的公開根節點,建立專用的 PKCS12 信任儲存庫。 不要修改已安裝的 JDK cacerts 檔案或覆蓋現有的信任儲存庫。

    keytool -importkeystore -srckeystore "<jdk-home>/lib/security/cacerts" -destkeystore "<trust-store-file>" -deststoretype PKCS12
    

    請在提示中輸入新的目的地商店密碼。 對於來源儲存密碼,請使用你的 JDK 提供者或管理員提供的值。 複製公用根憑證可保有對使用公用 CA 的伺服器之信任。

  3. 把已驗證的 CA 加到專屬商店。

    keytool -importcert -alias sql-server-ca -file "<ca-certificate-file>" -keystore "<trust-store-file>" -storetype PKCS12
    

    輸入目的地商店密碼。 在確認匯入前,請檢查顯示的指紋是否與驗證的數值相符。

在你執行 Maven 的終端機中設定這兩個可選變數。 請使用您剛建立的目的地存放區密碼。 PowerShell 密碼提示字元需要 PowerShell 7.1 或更新版本。

$env:SQL_TRUST_STORE = "<trust-store-file>"
$env:SQL_TRUST_STORE_PASSWORD = Read-Host "Trust-store password" -MaskInput

Java 應用程式會讀取這些變數,並明確設定其 JDBC 信任儲存。 省略兩個變數,以使用 Java 虛擬機(JVM)預設的信任設定。 保持 encrypt=true 和 trustServerCertificate=false。

Maven 為此應用程式啟動獨立的 Java 程序。 使用 mvn -D... 或 MAVEN_OPTS 設定 Java 安全通訊端擴充功能(JSSE)屬性(例如 javax.net.ssl.trustStore)並不會設定該子處理程序。 JAVA_TOOL_OPTIONS 和 JDK_JAVA_OPTIONS 都可存取到它,但 JVM 在啟動時會回顯這些選項。 密碼不要放在任何變數裡。 請使用本節的應用變數。 欲了解更多信任設定,請參閱 「配置客戶端進行加密」。

新增 Java 應用程式

從該jdbc-quickstart目錄建立 Java 原始碼目錄。

New-Item -ItemType Directory -Path src\main\java -Force | Out-Null

將以下完整應用程式以 Quickstart.java 為檔名儲存在 src/main/java 中。

Transact-SQL(T-SQL)查詢 SELECT CAST(? AS int) + 1 AS answer 接受一個參數。 setInt 將值 41 與 SQL 文字分開綁定。 預期結果是恰好有一列包含 42。

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

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class Quickstart {
    public static void main(String[] args) throws SQLException {
        SQLServerDataSource dataSource = new SQLServerDataSource();
        dataSource.setServerName(required("SQL_SERVER_NAME"));
        dataSource.setDatabaseName(required("SQL_DATABASE_NAME"));
        dataSource.setPortNumber(Integer.parseInt(required("SQL_PORT")));
        dataSource.setEncrypt("true");
        dataSource.setTrustServerCertificate(false);
        dataSource.setLoginTimeout(30);

        String authentication = required("SQL_AUTHENTICATION");
        switch (authentication) {
            case "ActiveDirectoryInteractive":
            case "ActiveDirectoryManagedIdentity":
                break;
            case "SqlPassword":
                dataSource.setUser(required("SQL_USER"));
                dataSource.setPassword(required("SQL_PASSWORD"));
                break;
            default:
                throw new IllegalArgumentException(
                        "SQL_AUTHENTICATION must be ActiveDirectoryInteractive, "
                        + "ActiveDirectoryManagedIdentity, or SqlPassword.");
        }
        dataSource.setAuthentication(authentication);

        if (System.getenv("SQL_TRUST_STORE") != null
                || System.getenv("SQL_TRUST_STORE_PASSWORD") != null) {
            dataSource.setTrustStore(required("SQL_TRUST_STORE"));
            dataSource.setTrustStorePassword(required("SQL_TRUST_STORE_PASSWORD"));
            dataSource.setTrustStoreType("PKCS12");
        }

        String sql = "SELECT CAST(? AS int) + 1 AS answer";
        try (Connection connection = dataSource.getConnection();
             PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setInt(1, 41);
            statement.setQueryTimeout(30);
            try (ResultSet results = statement.executeQuery()) {
                if (!results.next() || results.getInt("answer") != 42 || results.next()) {
                    throw new SQLException("Expected exactly one row with answer = 42.");
                }
            }
        }
        System.out.println("Verified result: 42");
    }

    private static String required(String name) {
        String value = System.getenv(name);
        if (value == null || value.isBlank()) {
            throw new IllegalArgumentException("Set environment variable " + name + ".");
        }
        return value;
    }
}

應用程式會將登入和查詢逾時設定為 30 秒。 互動式認證有獨立的憑證等待限制,詳見 第一次執行的故障排除。 應用程式會使用 try-with-resources 機制關閉結果集、預備陳述式和連線,即使發生例外也一樣。 錯誤會傳播並導致程序以非零狀態退出。

執行並驗證

在 jdbc-quickstart 目錄中執行:

mvn -q compile exec:exec

Maven 會下載相依、編譯應用程式,並啟動一個獨立的 Java 程序。 對於 ActiveDirectoryInteractive,請在瀏覽器中完成登入,然後返回終端機。

查詢成功且應用程式關閉資源後,會列印:

Verified result: 42

瀏覽器訊息驗證完成並不代表資料庫連線成功。 檢查應用程式的結果以及退出狀態是否為零: $LASTEXITCODE 在 PowerShell 或 $? Bash 中。 查詢不依賴任何現有資料表,也不會留下資料需要清理。

如果你用過 SQL 認證,完成後就從終端機環境移除 SQL_PASSWORD 。 在 PowerShell 中,執行 Remove-Item Env:\SQL_PASSWORD。 在 Bash 中,執行 unset SQL_PASSWORD。

如果你設定了 private-CA 信任儲存,也要移除它的環境變數。 在 PowerShell 中,執行 Remove-Item Env:\SQL_TRUST_STORE, Env:\SQL_TRUST_STORE_PASSWORD。 在 Bash 中,執行 unset SQL_TRUST_STORE SQL_TRUST_STORE_PASSWORD。 只保留信託存檔直到你需要為止。

第一次執行時要排除問題

癥狀 Action
Set environment variable ... 在執行 Maven 的終端機中設定命名變數。 整合開發環境(IDE)可能需要自己的執行設定。
Java 編譯或類別版本錯誤 執行 mvn -version 並確認 Maven 使用的是 JDK 21。 如果 Maven 和 java -version 回報的執行環境不同,請勾選 JAVA_HOME。
缺少認證函式庫 將 azure-identity 相依性保留在 pom.xml 中,並使用 Maven 執行應用程式,使其包含傳遞相依性。
登入逾時或連線被拒絕 檢查伺服器主機名稱、TCP 埠口、資料庫可用性和網路存取。
互動式登入已逾時 驅動程式對互動式權杖要求的等待時間最多為 20 秒。 請及時完成登入。 如果請求逾時,請再執行一次指令。 增加 loginTimeout 代幣等待時間不會延長。
Microsoft Entra 登入成功,但資料庫存取失敗 確認你登入的是正確的租戶,且你的身份有權存取所選的資料庫。 請檢查 Azure SQL 資料庫的使用者或 Fabric 權限(如適用)。
憑證驗證失敗,其中包括 PKIX path building failed 追蹤 Trust,一個私人憑證機構 ,為私人發行人服務。 使用 Server 憑證涵蓋的 DNS 名稱連接。 不要用 trustServerCertificate=true. 來繞過驗證。

如需其他診斷資訊,請參閱連線疑難排解。