JDBC 驅動與連線字串實戰:從預設 `system/test` 到業務資料庫與應用帳號
這篇文章有個前提要先說清楚:預設你已經把基礎環境弄好了,我這裡以 Windows 用戶端和 Linux 伺服器端為例,也就是說 Windows 11 本機開發機能存取 CentOS 7.6 伺服器,金倉資料庫實例已經跑起來,埠、防火牆、遠端存取規則也都配好了。Windows 安裝、CentOS 安裝,還有 Windows 連 CentOS 上的資料庫這幾塊,前面的文章裡已經單獨講過,這裡不再重複。
前置教學可參考:
應用連線資料庫失敗,往往不是業務程式碼複雜,而是最基礎的三件事沒對齊:驅動包、連線字串、帳號權限。本文從剛安裝完成後的預設狀態開始,先用 system 帳號連線預設 test 資料庫,再建立本專欄後續統一使用的業務資料庫、Schema、應用帳號和測試表,最後用一個最小 Java 程式完成 JDBC 查詢驗證。
@[toc]
本篇要完成五件事:
system/test 連線遠端伺服器。統一環境如下,表中 IP 僅為示例,實際使用時替換為自己的伺服器位址:
項目示例值本機系統Windows 11伺服器系統CentOS 7.6資料庫伺服器 IP192.168.10.101資料庫連接埠54321初始資料庫test初始使用者system業務資料庫kb_app業務 Schemashop應用帳號app_user唯讀帳號report_user測試表shop.t_connection_check開始寫 Java 程式前,先用預設帳號確認這條鏈路已經能手動連線:
cmd 代码解读复制代码ksql -h 192.168.10.101 -p 54321 -U system -d test
這裡如果還連不上,先回到跨平台連線教學排查網路、監聽位址、防火牆和驗證規則。本專欄從「預設 system/test 已經能遠端連線」這個前提出發。
預設的那個 test 資料庫,適合做初始驗證。但是直接拿它做後續應用開發的資料庫,不太建議。那我們先用 system 使用者建一個業務資料庫 kb_app:
sql 代码解读复制代码CREATE DATABASE kb_app;
退出目前連線。接著重新連到 kb_app:
cmd 代码解读复制代码ksql -h 192.168.10.101 -p 54321 -U system -d kb_app
然後我們建立業務 Schema、應用帳號還有唯讀帳號:
sql 代码解读复制代码CREATE SCHEMA shop;
CREATE USER app_user WITH PASSWORD 'App_user_123';
CREATE USER report_user WITH PASSWORD 'Report_user_123';
GRANT USAGE ON SCHEMA shop TO app_user;
GRANT USAGE ON SCHEMA shop TO report_user;
GRANT CREATE ON SCHEMA shop TO app_user;
如果你環境裡已經有同名資料庫、Schema 或者使用者了。那你先確認一下,它們是不是本文要建立的這些。如果不是的話,我建議你換個業務資料庫名稱或者帳號名稱。這樣能避免誤操作既有環境。
接著我們建立本專欄第一張測試表:
sql 代码解读复制代码CREATE TABLE shop.t_connection_check (
id INT PRIMARY KEY,
check_name VARCHAR(64),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO shop.t_connection_check(id, check_name)
VALUES (1, 'jdbc_check_ready');
給應用帳號讀寫權限。唯讀帳號給個查詢權限就行:
sql 代码解读复制代码GRANT SELECT, INSERT, UPDATE, DELETE ON shop.t_connection_check TO app_user;
GRANT SELECT ON shop.t_connection_check TO report_user;
最後用應用帳號驗證一次:
cmd 代码解读复制代码ksql -h 192.168.10.101 -p 54321 -U app_user -d kb_app
進去後執行:
sql 代码解读复制代码SELECT current_database(), current_user;
SELECT * FROM shop.t_connection_check;
要是你能看到 kb_app、app_user 還有 jdbc_check_ready 這筆記錄。那就說明,後面需要的基礎物件都準備好了。
JDBC 驅動這個東西,通常來說,在金倉資料庫安裝目錄、用戶端工具目錄,或者官方提供的驅動包裡都能找到。本文 Windows 安裝目錄示例用的是 D:\Tools\Kingbase。你安裝路徑不一樣的話,記得換成自己的實際目錄。
在 Windows 11 上我們可以先搜尋一下驅動包。下面這個命令是以我本機路徑為例的。執行的時候把 $kbHome 換成你自己的實際安裝目錄就行:
powershell 代码解读复制代码$kbHome = "D:\Tools\Kingbase"
Get-ChildItem -LiteralPath $kbHome -Recurse -File -Filter "kingbase*.jar" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like "*\Interface\jdbc\*" } |
Select-Object FullName
我環境裡搜尋到的 KingbaseES V9R2C13 JDBC 驅動路徑是這樣的:
text 代码解读复制代码D:\Tools\Kingbase\KESV9R2C13\KES\KESRealPro\V009R002C013\Interface\jdbc\kingbase8-9.0.0.jar
同一個目錄下,你可能還會看到 kingbase8-9.0.0.jre6.jar、kingbase8-9.0.0.jre7.jar 這種。這種是相容舊 JRE 的包。我們本機用的 JDK 比較新的話,直接選 kingbase8-9.0.0.jar 就行了。
找到 JDBC 驅動後,我建議你統一複製到專案的 lib 目錄。比如像這樣:
text 代码解读复制代码kb-jdbc-demo
|-- lib
| `-- kingbase8-9.0.0.jar
|-- src
| `-- DbConnectCheck.java
複製命令如下:
powershell 代码解读复制代码New-Item -ItemType Directory -Force -Path .\lib
Copy-Item -LiteralPath "D:\Tools\Kingbase\KESV9R2C13\KES\KESRealPro\V009R002C013\Interface\jdbc\kingbase8-9.0.0.jar" `
-Destination ".\lib\kingbase8-9.0.0.jar" `
-Force
如果你專案用的是 Maven 或者 Gradle。那優先按企業層級裡的內部製品庫,或者官方建議的方式去引入驅動。本文為了減少前置依賴,先用最小 Java 檔案示範一下。
應用連線資料庫的核心就是 JDBC URL。範例形式如下:
text 代码解读复制代码jdbc:kingbase8://192.168.10.101:54321/kb_app
其實拆開來看很簡單,就是幾段拼在一起:
jdbc:kingbase8:JDBC 協議和驅動識別前綴,以實際驅動說明為準。192.168.10.101:CentOS 資料庫伺服器 IP。54321:資料庫監聽埠。kb_app:剛才建立的業務資料庫名稱。如果你的環境啟用了額外安全參數或字元集參數,需要按驅動文件追加到 URL 後面。初次接入的話,不建議一次性堆很多參數,先用最小連線字串打通,再逐步增加連線逾時、應用名稱等參數。
新建 src\DbConnectCheck.java:
java 代码解读复制代码import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class DbConnectCheck {
public static void main(String[] args) throws Exception {
String url = "jdbc:kingbase8://192.168.10.101:54321/kb_app";
String user = "app_user";
String password = "App_user_123";
String sql = "select id, check_name, created_at from shop.t_connection_check where id = ?";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement(sql)) {
System.out.println("connected=" + !conn.isClosed());
ps.setInt(1, 1);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
System.out.println("id=" + rs.getInt("id"));
System.out.println("check_name=" + rs.getString("check_name"));
System.out.println("created_at=" + rs.getTimestamp("created_at"));
} else {
System.out.println("no data found");
}
}
}
}
}
這段程式有幾個值得注意的地方:
PreparedStatement,不要把參數直接拼到 SQL 字串裡。try-with-resources,確保連線、語句、結果集都能正常關閉。進入專案目錄:
powershell 代码解读复制代码cd D:\work\kb-jdbc-demo
編譯:
powershell 代码解读复制代码javac -encoding UTF-8 -cp ".;lib\kingbase8-9.0.0.jar" src\DbConnectCheck.java
執行:
powershell 代码解读复制代码java -cp ".;lib\kingbase8-9.0.0.jar;src" DbConnectCheck
如果輸出類似下面內容,說明 JDBC 鏈路已經打通:
如果命令執行後很快返回但沒有任何結果,通常不是程式「卡住了」,而是查詢沒有列印出可見資訊。上面的範例會先輸出 connected=true,再輸出查詢結果。如果看到 no data found 的話,說明連線已經成功,但 shop.t_connection_check 中沒有 id = 1 這筆記錄,需要回到前面的建立資料表和插入步驟檢查一下。
如果你使用的是 PowerShell,注意 classpath 分隔符在 Windows 上是分號 ;。在 Linux 上執行的話,分隔符一般是冒號 :。
上面的寫法適合第一次驗證,但不適合長期維護。連線資訊不應該硬編碼在 Java 類裡。
可以先建一個簡單的設定檔 db.properties:
properties 代码解读复制代码db.url=jdbc:kingbase8://192.168.10.101:54321/kb_app
db.user=app_user
db.password=App_user_123
Java 中讀取設定:
java 代码解读复制代码import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
public class DbConfigCheck {
public static void main(String[] args) throws Exception {
Properties props = new Properties();
try (FileInputStream in = new FileInputStream("db.properties")) {
props.load(in);
}
try (Connection conn = DriverManager.getConnection(
props.getProperty("db.url"),
props.getProperty("db.user"),
props.getProperty("db.password"))) {
System.out.println("connected=" + !conn.isClosed());
System.out.println("database=" + conn.getCatalog());
}
}
}
這樣做的好處是,後續遷移到 Spring Boot、測試環境、生產環境時,連線資訊可以交給配置中心、環境變數或啟動參數管理,不需要動程式碼。
不要只看到程式沒有報錯就算接入成功。至少做三類驗證。
確認目前連線到底使用了哪個資料庫和哪個帳號:
sql 代码解读复制代码SELECT current_database(), current_user;
可以在 Java 程式裡執行這條 SQL,也可以透過 ksql 對照。
用 app_user 測試正常讀寫:
sql 代码解读复制代码INSERT INTO shop.t_connection_check(id, check_name)
VALUES (2, 'jdbc_insert_ok');
SELECT * FROM shop.t_connection_check WHERE id = 2;
再用 report_user 連線 kb_app 測試唯讀,確認它能查詢 shop.t_connection_check,但不能執行寫入操作。
故意把密碼寫錯,看應用是否能清楚輸出驗證失敗;故意把 IP 寫錯,看是否有連線逾時;故意把表名寫錯,看是否能定位 SQL 錯誤。上線前先看過這些錯誤,後面排障會快很多。
通常是 JDBC jar 沒放進 classpath,或者驅動版本和連線字串前綴不匹配。先確認執行命令裡包含了驅動 jar。
這不是 Java 程式問題,優先回到前置跨平台連線教學,檢查埠監聽、防火牆、安全群組和資料庫監聽位址。
檢查使用者名稱、密碼、資料庫名稱、驗證規則和帳號是否被鎖定。本文前半部分使用 system/test 做初始連線,後半部分使用 app_user/kb_app 做應用連線,排查時不要把這兩組帳號和資料庫混在一起。
如果表確實存在,重點檢查 Schema。建議 SQL 中明確寫 shop.t_connection_check,不要依賴預設搜尋路徑。
先確認資料庫、用戶端、Java 原始檔、主控台輸出編碼。Windows 命令列環境下可以優先使用 PowerShell,並在編譯時指定 -encoding UTF-8。
JDBC 接入的核心不是寫多少程式碼,而是把驅動、連線字串、帳號權限和驗證 SQL 做對。本文從預設 system/test 起步,建立了後續專欄統一使用的 kb_app、shop、app_user、report_user 和 shop.t_connection_check,並用最小 Java 程式完成了第一次 JDBC 查詢驗證。
下一篇我們進入 Spring Boot,把單檔連線驗證升級成更貼近真實專案的應用設定方式。