初學者編寫 JDBC 登錄代碼時,常犯以下錯誤:
String sql = "select Count(*) as login from Admin where LoginId = ? and LoginPwd = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, id);
ps.setString(2, pwd);
int r = ps.executeQuery(); // 編譯錯誤:不能將 ResultSet 轉換為 int
System.out.println(r == 1 ? "登錄成功!" : "登錄失敗!");
PreparedStatement.executeQuery() 返回的是 ResultSet 對象,而非整數。即使 SQL 使用 COUNT(*),結果也是一個包含單行單列的結果集,必須通過 ResultSet.next() 移動游標並調用 getInt() 取值。
String sql = "select Count(*) as login from Admin where LoginId = ? and LoginPwd = ?";
try (Connection conn = DriverManager.getConnection(url, user, pass);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, id);
ps.setString(2, pwd);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
int count = rs.getInt("login"); // 或 rs.getInt(1)
if (count == 1) {
System.out.println("登錄成功!");
} else {
System.out.println("登錄失敗:用戶名或密碼錯誤");
}
} else {
System.out.println("登錄失敗:查詢無結果");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
Connection、PreparedStatement、ResultSet,防止資源洩漏(JDK 7+)。rs.next() 移動到第一行數據。rs.getInt("login") 或列索引 rs.getInt(1)。PreparedStatement 參數化查詢,已正確實現。示例中密碼明文比對極不安全。生產環境應:
SELECT password_hash FROM Admin WHERE LoginId = ?,再在 Java 中驗證。| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
int r = ps.executeQuery(); | 返回類型不匹配 | ResultSet rs = ps.executeQuery(); |
if (rs.getInt(1) > 0) 未先調用 next() | 游標未定位,拋出異常 | if (rs.next() && rs.getInt(1) > 0) |
| 未關閉資源 | 連接洩漏,導致數據庫連接池耗盡 | try-with-resources 或 finally 關閉 |
JDBC 查詢單值(如 COUNT、MAX、單列單行)時,必須獲取 ResultSet、調用 next()、再取列值。配合 try-with-resources 管理資源,即可編寫健壯、無洩漏的登錄邏輯。切記:生產環境務必對密碼進行強哈希存儲,切勿明文比對。