首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

JDBC 登錄功能常見錯誤:executeQuery 返回 ResultSet 而非 int 的正確處理

     編輯:程式設計疑難解答

問題代碼分析

初學者編寫 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();
}

關鍵點解析

  1. 使用 try-with-resources:自動關閉 Connection、PreparedStatement、ResultSet,防止資源洩漏(JDK 7+)。
  2. ResultSet 游標初始位置在第一行之前:必須調用 rs.next() 移動到第一行數據。
  3. 獲取列值:可用列別名 rs.getInt("login") 或列索引 rs.getInt(1)。
  4. SQL 注入防護:使用 PreparedStatement 參數化查詢,已正確實現。

進階建議:避免明文密碼存儲

示例中密碼明文比對極不安全。生產環境應:

  • 密碼存儲 BCrypt/Argon2/PBKDF2 哈希值(含鹽)。
  • 登錄時查詢用戶記錄,取出哈希值,在應用層用同樣算法驗證。
  • 或使用 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 管理資源,即可編寫健壯、無洩漏的登錄邏輯。切記:生產環境務必對密碼進行強哈希存儲,切勿明文比對。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved