JDBC总是测试MySQL表的最后一行?

时间:2010-01-13 18:41:58

标签: java mysql jdbc

我有一个Manager类,可以在SQL表中保存数据,也可以从SQL表中获取结果并测试这些数据。当我运行程序时,会显示一帧获取ID和密码,如果它们是正确的,其他框架将会显示。但我不知道为什么它只是测试SQL表的最后一行?我的意思是,如果我将这些文本字段设置为除了最后一行之外的其他ID和密码。它将显示数据是错误的(我之前为错误的数据设置了它)

经理班:

 public static boolean Test(String userName, String password) {
    boolean bool = false;
    Statement stmt = null;
    try {
        stmt = conn.createStatement();

        ResultSet rst = null;

        rst = stmt.executeQuery("SELECT yahooId , password FROM clienttable");


        while (rst.next()) {
            if (rst.getString(1).equalsIgnoreCase(userName) && rst.getString(2).equalsIgnoreCase(password)) {
                bool = true;
            } else {
                bool = false;
            }
        }
    } catch (SQLException ex) {
        Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
    }
    return bool;



}

我的按钮在框架中执行操作,获取ID和密码并进行测试:

 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    try {
        submit();
    } catch (ConnectException ex) {
        JOptionPane.showMessageDialog(this, "You coudn't connect to the server successfully,try it again", "Sign_In Problem", JOptionPane.OK_OPTION);

    }
    clear();

} 

  private void submit() throws ConnectException {

    String id = idField.getText();
    char[] pass1 = passField.getPassword();
    String pass = new String(pass1);
    if (id.equals("") || pass.equals("")) {
        Toolkit.getDefaultToolkit().beep();
        JOptionPane.showMessageDialog(this, "You should enter an ID and password", "Sign_In Problem", JOptionPane.OK_OPTION);
        return;
    } else {
        boolean b = Manager.Test(id, pass);
        client.setCurrentName(id);
        if (b == true) {
            this.setVisible(false);



            ListFrame frame = new ListFrame(client);
            frame.setVisible(true);





        } else {

            JOptionPane.showMessageDialog(this, "You have entered wrong datas,try it again", "Sign_In Problem", JOptionPane.OK_OPTION);
            return;
        }
    }
}

编辑:

我已经编辑了我的经理课程(测试方法),但它仍然像过去那样工作!!

  public static boolean Test(String userName, String password) {
    boolean bool = false;
    PreparedStatement stmt = null;
    ResultSet resultSet = null;
    try {
        stmt = conn.prepareStatement("SELECT id FROM clienttable WHERE yahooId = ? AND password = ?");
        stmt.setString(1, userName);
        stmt.setString(2, password);
        resultSet = stmt.executeQuery();
        bool = resultSet.next();

    } catch (SQLException ex) {
        Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        try {
            resultSet.close();
            stmt.close();
            conn.close();
        } catch (SQLException ex) {
            Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    return bool;



}

2 个答案:

答案 0 :(得分:7)

因为您将整个数据库表拖入Java内存并在while循环中测试每个行。如果找到匹配项,则不会中断循环,以便它继续覆盖布尔结果,直到最后一行。

那就是说,你真的不想在Java中进行比较。只需使用SQL WHERE clause即可。这很多更有效率,而且确实是DB应该做的任务。不要试图接管DB在Java中的工作,它只会效率低下。

public boolean exists(String username, String password) throws SQLException {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    boolean exists = false;

    try {
        connection = database.getConnection();
        preparedStatement = connection.prepareStatement("SELECT id FROM client WHERE username = ? AND password = ?");
        preparedStatement.setString(1, username);
        preparedStatement.setString(2, password);
        resultSet = preparedStatement.executeQuery();
        exists = resultSet.next();
    } finally {
        close(resultSet);
        close(preparedStatement);
        close(connection);
    }

    return exists;
}

您看到我做了一些改进:

  1. 使用preparedstatement。
  2. 不要使用equalsignorecase。密码“FooBar”不应与“foobar”相同。
  3. 轻轻获取并关闭相同范围内的资源以避免泄漏。
  4. 使用独立且可重复使用的非静态DAO方法。
  5. 要了解有关使用JDBC的更多信息,请找到this basic tutorial有用的正确方法。

答案 1 :(得分:2)

简单的答案是你的while循环应该在你找到匹配时终止,所以它应该是:

    while (rst.next() && bool == false) {
        if (rst.getString(1).equalsIgnoreCase(userName) && rst.getString(2).equalsIgnoreCase(password)) {
            bool = true;
        }
    }

请注意,仅选择与您的用户ID匹配的行会更高效。密码,类似于以下内容:(请注意,错误处理留给读者练习)

PreparedStatement stmt;    stmt = conn.prepareStatement(“SELECT yahooId,password FROM clienttable WHERE yahooId =?”);    stmt.setString(1,“userName”);
   ResultSet rst = null;    rst = stmt.executeQuery();

if(rs!= null&& rs.getString(“password”)。equals(password)){       bool = true;    }