JDBC всегда проверяет последнюю строку таблицы MySQL? - PullRequest
1 голос
/ 13 января 2010

У меня есть класс Manager, который сохраняет данные в таблице SQL, а также получает результат из таблицы SQL и проверяет эти данные. Когда я запускаю свою программу, будет показан один кадр, который получает идентификатор и пароль, и если они верны, будет показан другой кадр. Но я не знаю, почему он просто тестирует последнюю строку таблицы SQL? Я имею в виду, если я установлю эти текстовые поля с другими идентификаторами и паролями, кроме последней строки. Это покажет, что данные неверны (я установил их ранее для неправильных данных)

Класс менеджера:

 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;
        }
    }
}

EDIT:

Я отредактировал свой класс менеджера (метод тестирования), но все равно он работает как в прошлом !!

  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 ]

7 голосов
/ 13 января 2010

Поскольку вы перетаскиваете всю таблицу базы данных в память Java и тестируете каждую строку в цикле while. Вы не прерываете цикл, если найдено совпадение, так что он продолжает перезаписывать логический результат до последней строки.

Тем не менее, вы действительно не хотите делать сравнение в Java. Просто используйте предложение SQL WHERE . Это намного более эффективно и действительно задача, которую БД должна делать. Не пытайтесь взять на себя работу БД в 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. Используйте подготовленное заявление.
  2. Не используйте equalsignorecase. Пароль «FooBar» НЕ должен совпадать с «foobar».
  3. Осторожно приобретайте и закрывайте ресурсы в том же объеме, чтобы избежать утечки.
  4. Имейте это в независимом и повторно используемом нестатическом методе DAO.

Чтобы узнать больше о правильном использовании JDBC, вам может пригодиться этот базовый урок .

2 голосов
/ 13 января 2010

Простой ответ заключается в том, что ваш цикл while должен завершиться, когда вы найдете совпадение, поэтому он должен читать:

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

Обратите внимание, что было бы более эффективно выбирать только строки, соответствующие вашему идентификатору пользователя и паролю, что-то вроде следующего: (обратите внимание, что обработка ошибок оставлена ​​в качестве упражнения для читателя)

PreparedStatement stmt; stmt = conn.prepareStatement ("ВЫБЕРИТЕ yahooId, пароль ОТ клиентской таблицы ГДЕ yahooId =?"); stmt.setString (1, "userName");
ResultSet rst = null; rst = stmt.executeQuery ();

if (rs! = Null && rs.getString ("пароль"). Равно (пароль)) { bool = true; }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...