Java JDBC总是测试MySQL表的最后一行吗?
我有一个管理类,它可以将数据保存在SQL表中,还可以从SQL表中获取结果并测试这些数据。当我运行程序时,会显示一个帧,其中一个帧可以获取ID和密码,如果它们正确,则会显示另一个帧。但我不知道为什么它只测试SQL表的最后一行??我的意思是,若我用除最后一行之外的其他ID和密码设置这些文本字段,它将显示数据是错误的,我以前设置的数据是错误的 经理级:Java JDBC总是测试MySQL表的最后一行吗?,java,mysql,jdbc,Java,Mysql,Jdbc,我有一个管理类,它可以将数据保存在SQL表中,还可以从SQL表中获取结果并测试这些数据。当我运行程序时,会显示一个帧,其中一个帧可以获取ID和密码,如果它们正确,则会显示另一个帧。但我不知道为什么它只测试SQL表的最后一行??我的意思是,若我用除最后一行之外的其他ID和密码设置这些文本字段,它将显示数据是错误的,我以前设置的数据是错误的 经理级: public static boolean Test(String userName, String password) { boolean
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;
}
}
}
编辑:
我已经编辑了我的manager类测试方法,但它仍然像过去一样工作
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;
}
因为您正在将整个数据库表拖到Java内存中,并在while循环中测试每一行。如果找到匹配项,则不会中断循环,从而继续覆盖布尔结果,直到最后一行 也就是说,您真的不想在Java中进行比较。只要利用这个机会。这样做效率更高,而且实际上是DB应该完成的任务。不要试图在Java中接管DB的工作,这只会导致效率低下
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;
}
您可以看到,我做了一些增强:
使用preparedstatement。
不要使用equalsignorecase。FooBar的密码不应与FooBar相同。
轻轻获取并关闭同一范围内的资源,避免泄漏。
将其放在独立且可重用的非静态DAO方法中。
要了解有关如何正确使用JDBC的更多信息,您可能会发现这很有用。因为您正在将整个数据库表拖到Java内存中,并在while循环中测试每一行。如果找到匹配项,则不会中断循环,从而继续覆盖布尔结果,直到最后一行 也就是说,您真的不想在Java中进行比较。只要利用这个机会。这样做效率更高,而且实际上是DB应该完成的任务。不要试图在Java中接管DB的工作,这只会导致效率低下
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;
}
您可以看到,我做了一些增强:
使用preparedstatement。
不要使用equalsignorecase。FooBar的密码不应与FooBar相同。
轻轻获取并关闭同一范围内的资源,避免泄漏。
将其放在独立且可重用的非静态DAO方法中。
要了解有关使用JDBC的更多信息,您可能会发现正确的方法很有用。简单的答案是,当您找到匹配项时,while循环应该终止,因此它应该是:
while (rst.next() && bool == false) {
if (rst.getString(1).equalsIgnoreCase(userName) && rst.getString(2).equalsIgnoreCase(password)) {
bool = true;
}
}
请注意,只选择与您的用户id和密码匹配的行会更有效,如下所示:请注意,错误处理留给读者作为练习
编制报表;
stmt=conn.prepareStatementSELECT yahooId,密码来自clienttable,其中yahooId=?;
stmt.setString,用户名;
结果集rst=null;
rst=stmt.executeQuery
如果是rs!=null&&rs.getStringpassword.equalspassword{
布尔=真;
}简单的答案是,当找到匹配项时,while循环应该终止,因此它应该是:
while (rst.next() && bool == false) {
if (rst.getString(1).equalsIgnoreCase(userName) && rst.getString(2).equalsIgnoreCase(password)) {
bool = true;
}
}
请注意,只选择与您的用户id和密码匹配的行会更有效,如下所示:请注意,错误处理留给读者作为练习
编制报表;
stmt=conn.prepareStatementSELECT yahooId,密码来自clienttable,其中yahooId=?;
stmt.setString,用户名;
结果集rst=null;
rst=stmt.executeQuery
如果是rs!=null&&rs.getStringpassword.equalspassword{
布尔=真;
}我想我们可能需要更多的信息,而不是无法正常工作的信息@巴卢斯的答案和你所掌握的信息一样好provided@Johanna:那么问题就出在别的地方了。调试它。如果您的意思是返回false,那么它只是意味着数据库中没有匹配项:顺便说一下,您编辑的代码在JDBC透视图中仍然是错误的。您仍然在泄漏连接,并且没有在各自的try-catch中关闭资源,更糟糕的是,整个方法仍然是静态的。当你的应用程序在生产中广泛使用时,它迟早会崩溃。@Johanna:如果你需要更多的帮助,你真的,真的需要学会用聪明的方式提问。直截了当地说这不管用!我们真的没有什么可以合作的。详细说明到底发生了什么,也详细说明到底发生了什么,即你的期望。关于细节,我的意思是在代码开发人员级别,而不是在最终用户级别。我想我们可能需要更多的信息,而不是它不能正常工作@巴卢斯的答案和你所掌握的信息一样好provided@Johanna:那么问题就出在别的地方了。调试它。如果您的意思是返回false,那么它只是意味着数据库中没有匹配项:顺便说一下,您编辑的代码在JDBC透视图中仍然是错误的。你还在泄露秘密
连接和不关闭每个资源都有自己的try-catch,更糟糕的是,整个方法仍然是静态的。当你的应用程序在生产中广泛使用时,它迟早会崩溃。@Johanna:如果你需要更多的帮助,你真的,真的需要学会用聪明的方式提问。直截了当地说这不管用!我们真的没有什么可以合作的。详细说明到底发生了什么,也详细说明到底发生了什么,即你的期望。具体来说,我指的是代码开发人员级别,而不是最终用户级别。