英文:
JDBC and MySQL Statement and ResultSet error
问题
我正在尝试运行以下代码:
Scanner input = new Scanner(System.in);
ResultSet rs = null;
System.out.print("用户名:");
String username = input.next();
System.out.print("\n密码:");
String pword = input.next();
String stmt = "SELECT * FROM accounts WHERE username = '" + username + "' AND password = '" + pword + "' ";
Statement s = con.createStatement(); // con = Connection对象
rs = s.executeQuery(stmt);
if (rs.absolute(1)) {
System.out.println("登录成功");
} else {
System.out.println("无效登录");
}
然而,我遇到了以下错误:
java.sql.SQLException: ResultSet.TYPE_FORWARD_ONLY 类型的结果集不允许进行此操作。
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.result.ResultSetImpl.absolute(ResultSetImpl.java:391)
at practice.JDBCtester.login(JDBCtester.java:36)
at practice.JDBCtester.main(JDBCtester.java:17)
有人能解释一下我的代码存在的问题吗?
英文:
I am trying to run the following code:
Scanner input = new Scanner(System.in);
ResultSet rs = null;
System.out.print("Username: ");
String username = input.next();
System.out.print("\nPassword: ");
String pword = input.next();
String stmt = "SELECT * FROM accounts WHERE username = '"+username+"' AND password = '"+pword+"' ";
Statement s = con.createStatement(); // con = Connection object
rs = s.executeQuery(stmt);
if(rs.absolute(1)) {
System.out.println("LOGIN SUCCESSFUL");
}
else {
System.out.println("INVALID LOGIN");
}
However, I end up with the following error:
java.sql.SQLException: Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.result.ResultSetImpl.absolute(ResultSetImpl.java:391)
at practice.JDBCtester.login(JDBCtester.java:36)
at practice.JDBCtester.main(JDBCtester.java:17)
Could someone explain the problem with my code?
答案1
得分: 3
不使用absolute()
,您可以验证是否至少返回了一行。例如,您可以执行以下操作:
rs = s.executeQuery(stmt);
if (rs.next()) {
System.out.println("登录成功");
}
else {
System.out.println("无效登录");
}
absolute()
是一个高级方法,适用于读取、重新读取和更新特殊类型的结果集。您的结果集是一个简单的结果集。
英文:
Instead of using absolute()
you can just verify at least one row was returned. For example you can do:
rs = s.executeQuery(stmt);
if (rs.next()) {
System.out.println("LOGIN SUCCESSFUL");
}
else {
System.out.println("INVALID LOGIN");
}
absolute()
is an advanced method useful for reading, re-reading, and updating special types of result sets. Your result set is a simple one.
答案2
得分: 1
如在 ResultSet.absolute(int)
中记录:
> 抛出:
> SQLException
- 如果发生数据库访问错误;如果在关闭的结果集上调用此方法或结果集类型为 TYPE_FORWARD_ONLY
,则会调用此方法
在大多数情况下,默认的结果集类型是 TYPE_FORWARD_ONLY
,因此不支持 absolute
方法。
而是使用 ResultSet.next()
来检查是否至少有一行。
正如我之前评论的,您当前的代码非常不安全。不要将值连接到查询字符串中(尤其不要使用从用户获取的值),因为这会使您的代码容易受到 SQL 注入攻击。而是使用带有参数占位符的准备好的语句。还不要存储明文密码,而是使用适当的密码哈希算法。
英文:
As documented in the ResultSet.absolute(int)
:
> Throws:
> SQLException
- if a database access error occurs; this method is called on a closed result set or the result set type is TYPE_FORWARD_ONLY
In most situations, the default result set type is TYPE_FORWARD_ONLY
, so the absolute
method is not supported.
Instead use ResultSet.next()
to check if there is at least one row.
As I also commented, your current code is highly insecure. Don't concatenate values into a query string (especially not values obtained from a user), as this makes your code vulnerable to SQL injection. Instead use a prepared statement with parameter placeholders. Also don't store plaintext passwords, but use an appropriate password hashing algorithm.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论