使用 jtds 驅動連線 MSSQL 時,開發者常面臨兩大難題:
1. 如何即時判斷連線是否成功(而非等待逾時)
2. 執行查詢後如何正確判斷結果集是否為空
String url = "jdbc:jtds:sqlserver://192.168.1.100:1433/DBName;user=sa;password=123;loginTimeout=5;socketTimeout=10";
Connection conn = null;
try {
conn = DriverManager.getConnection(url);
// 連線成功即執行到此,若失敗會拋出 SQLException
if (conn != null && !conn.isClosed()) {
Log.d("DB", "連線成功");
}
} catch (SQLException e) {
Log.e("DB", "連線失敗: " + e.getMessage());
// 此處可根據錯誤碼區分:網路不通、認證失敗、伺服器拒絕等
} finally {
// 注意:這裡不關閉連線,留給後續使用
}
關鍵參數說明:
loginTimeout:登入逾時秒數(建議 5-10 秒)socketTimeout:Socket 讀寫逾時(建議 10-30 秒)DriverManager.setLoginTimeout()Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM Users WHERE Age > 100");
// 正確判斷方式:使用 next() 移動游標
if (rs.next()) {
// 有資料,游標已指向第一筆
do {
String name = rs.getString("Name");
int age = rs.getInt("Age");
// 處理資料...
} while (rs.next());
} else {
// 無資料:rs.next() 回傳 false
Log.d("DB", "查無符合條件資料");
}
} catch (SQLException e) {
Log.e("DB", "查詢錯誤: " + e.getMessage());
} finally {
// 必須按順序關閉
try { if (rs != null) rs.close(); } catch (SQLException ignored) {}
try { if (stmt != null) stmt.close(); } catch (SQLException ignored) {}
}
| 錯誤做法 | 正確做法 | 原因 |
|---|---|---|
用 rs.getRow() == 0 判斷 | 用 !rs.next() 判斷 | 預設 ResultSet 為 TYPE_FORWARD_ONLY,getRow() 恆為 0 |
| 不關閉 ResultSet/Statement | finally 區塊逐層關閉 | 導致連線洩漏、資料庫鎖定 |
| 在 UI 執行緒執行資料庫操作 | 使用 AsyncTask、RxJava 或 Kotlin 協程 | ANR 崩潰、使用者體驗差 |
| 硬編碼連線字串 | 加密儲存於 SharedPreferences 或 Keystore | 資安風險、難以維護 |
SELECT 1)參考完整範例:Android jtds 連線 MSSQL 實戰教學