#java #sql
#java #sql
Вопрос:
Я пытаюсь создать форму входа и регистрации, используя Java и SQL Workbench. Форма регистрации работает правильно, так как имя пользователя и пароль добавляются в базу данных SQL. Что касается формы входа в систему, то все выглядит нормально. Но, когда она выполняется, она пропускает оператор If и переходит прямо к оператору Else. Имя пользователя и пароль указаны правильно, поскольку я проверил таблицу базы данных SQL. Результатом является исключение SqlSyntaxErrorException. Поэтому я думаю, что мой синтаксис неправильный. Любая помощь будет высоко оценена!
Это приведенный ниже код:
if (e.getSource() == LOG_IN_BUTTON)
{
String userName = USER_NAME_TEXTFIELD.getText();
String password = PASSWORD_TEXTFIELD.getText();
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/airline_connect",
"root", "Yasser1595");
String sql = "Select user_name, password from account where user_name=? and password=?";
st = connection.prepareStatement(sql);
st.setString(1, userName);
st.setString(2, password);
ResultSet rs = st.executeQuery(sql);
if (rs.next()) {
frame.dispose();
new MainGame();
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "You have successfully logged in");
} else {
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "Wrong Username amp; Password");
}
} catch (Exception exc) {
exc.printStackTrace();
}
}
Комментарии:
1. Можете ли вы проверить трассировку стека / сообщение об исключении. Он должен содержать больше информации о том, что не так с вашим синтаксисом.
2. @magicmn java.sql.SQLSyntaxErrorException: у вас ошибка в синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса для использования рядом ‘? и пароль =?’ в строке 1
3. @magicmn Это ошибка, я знаю, что это синтаксическая ошибка, и что-то не так с синтаксисом, но я не знаю, как решить эту проблему. И где находится «Строка 1»?
4. Обратите внимание, что вы никогда не должны хранить пароли в базе данных для входа в систему; вместо этого вы должны их хэшировать (используя специфичный для входа хэш, такой как BCrypt) и сравнивать их. В более общем плане, в реальных приложениях вы всегда должны использовать проверенные библиотеки для выполнения этой работы, но, похоже, это для вашего собственного обучения.
5. @chrylis-осторожно оптимистично — О, хорошо. Спасибо! Я рассмотрю это подробнее.
Ответ №1:
Попробуйте выполнить следующее,
ResultSet rs = st.executeQuery();
Не передавайте строку sql executeQuery
. Когда вы передаете строку sql executeQuery
, он рассматривает ее как обычный текст, а не как подготовленный оператор
Комментарии:
1. Спасибо за это, но это все равно не работает. Он по-прежнему переходит прямо к оператору Else.
2. Ранее это вызывало блок catch из-за синтаксической ошибки. Но теперь это будет блокировать else?
3. Да, я очень смущен.
4. Проверьте значения имени пользователя и пароля, которые вводятся в код через отладку или ведение журнала, и проверьте, правильно ли это. Также проверьте, есть ли какие-либо дополнительные пробелы во входных данных
5. Хорошо, я проверю это. Спасибо!
Ответ №2:
Вы не использовали PreparedStatement.executeQuery()
, но родительский Statement.executeQuery(sql)
, что является известной ошибкой. Также стоит использовать try-with-resources с локальными переменными. Не закрытие вещей может привести к утечке ресурсов.
String sql = "select user_name, password from account where user_name=? and password=?";
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/airline_connect",
"root", "Yasser1595");
PreparedStatement st = connection.prepareStatement(sql)) {
st.setString(1, userName);
st.setString(2, password);
try (ResultSet rs = st.executeQuery()) { // No sql parameter.
if (rs.next()) {
frame.dispose();
new MainGame();
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "You have successfully logged in");
return;
}
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "Wrong Username amp; Password");
}
} catch (SQLException exc) {
exc.printStackTrace();
}
Это все равно не сработало
- ПАРОЛЬ также является функцией, но поскольку синтаксических ошибок не произошло, это, вероятно, не проблема. Вы можете попробовать
"password"
(= имя столбца) . - В столбце может храниться не пароль, что представляет угрозу безопасности, если база данных будет украдена в будущем. Он может хранить некоторый хэш пароля.
Итак:
String sql = "SELECT user_name, "password" "
"FROM account "
"WHERE user_name=? AND "password"=PASSWORD(?)";
Сначала проверьте, как хранятся пароли (или их хэши).
Также может быть так, что обработка пароля выполняется на стороне Java, например, путем взятия MD5 пароля и его сохранения.
Если все должно работать, рассмотрите другую меру безопасности: если поле пароля является полем JPasswordField, в идеале оно должно работать не с a String
, а с a char[]
, которое может быть удалено после использования ( Arrays.setAll(pwdArray, ' ');
) . A String
может долго храниться в памяти, что может представлять угрозу безопасности.
Комментарии:
1. Спасибо за ответ, но он все равно не работает. Он по-прежнему переходит прямо к блоку Else.
2. Поскольку пароли обычно обрабатываются несколько косвенно, это может создать проблему. Вы можете сделать
SELECT user_name, password FROM account
, чтобы посмотреть, что хранится. Возможно, вы также тестировали специальный пароль char, который получает неправильную кодировку. Я расширил ответ.