使用 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 資源、系統指派管理身份的無頭應用程式:
- 啟用資源的受控識別。
- 請要求您的管理員授與該身分資料庫的存取權限。 對於 Azure SQL,請為該身份建立一個資料庫使用者。 對於 Fabric,請遵循 Fabric 的認證與存取要求,包括服務主體適用的租戶設定。
- 在主機的應用程式設定中設定
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>。 將信任儲存放在其他非特權使用者無法修改的目錄中。 如果有任何指令失敗就停止。
檢查加州憑證,並將其 SHA-256 指紋與管理員提供的數值做比較。
keytool -printcert -file "<ca-certificate-file>"透過複製 JDK 的公開根節點,建立專用的 PKCS12 信任儲存庫。 不要修改已安裝的 JDK
cacerts檔案或覆蓋現有的信任儲存庫。keytool -importkeystore -srckeystore "<jdk-home>/lib/security/cacerts" -destkeystore "<trust-store-file>" -deststoretype PKCS12請在提示中輸入新的目的地商店密碼。 對於來源儲存密碼,請使用你的 JDK 提供者或管理員提供的值。 複製公用根憑證可保有對使用公用 CA 的伺服器之信任。
把已驗證的 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. 來繞過驗證。 |
如需其他診斷資訊,請參閱連線疑難排解。