这是一个简单的代码,从数据库中打印一些行。 但是当我执行这个时,屏幕上不会打印任何内容。我认为问题是rs.next()
方法是跳过一行。那么我该如何避免这种情况或重置rs.next()
方法的位置呢?
String searchword = Searchtf.getText();
try {
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection con = DriverManager.getConnection(url, db_username, db_password);
java.sql.Statement stat = con.createStatement();
String searchQuery = "SELECT * FROM user WHERE Name LIKE '" + searchword + "' ";
java.sql.ResultSet rs = stat.executeQuery(searchQuery);
if (rs.next()) {
while (rs.next()) {
System.out.print(rs.getString("idUser") + " ,");
System.out.print(rs.getString("Name") + " ,");
System.out.print(rs.getString("Email") + " ,");
System.out.println(rs.getString("country") + " .");
}
} else {
JOptionPane.showMessageDialog(null, "Not Found");
}
} catch (Exception ex) {
ex.printStackTrace();
}
首先,停止像这样构建 SQL - 使用参数化 SQL 和PreparedStatement
。您当前的代码容易受到 SQL 注入攻击。
基本上,不要连续两次打电话给rs.next()
(第一次在if
,然后在while
中)......您可以通过将while
循环转换为do/while
循环来轻松做到这一点:
if (rs.next()) {
do {
System.out.print(rs.getString("idUser") + " ,");
System.out.print(rs.getString("Name") + " ,");
System.out.print(rs.getString("Email") + " ,");
System.out.println(rs.getString("country") + " .");
} while (rs.next());
}
或者只是使用while
循环,使用单独的变量来检测您是否看到了一些结果:
bool anyResults = false;
while (rs.next()) {
anyResults = true;
System.out.print(rs.getString("idUser") + " ,");
System.out.print(rs.getString("Name") + " ,");
System.out.print(rs.getString("Email") + " ,");
System.out.println(rs.getString("country") + " .");
}
if (!anyResults) {
JOptionPane.showMessageDialog(null, "Not Found");
}
(此外,您应该使用试用资源来关闭ResultSet
等,并且仅将堆栈跟踪打印到 stdout 几乎从来都不是处理异常的合适方法......
不,不需要使用 :
if (rs.next()) {
虽然足够了,这会使结果两次。 相反,您可以使用:
boolean b = false;
while (rs.next()) {
b = true;
...
}
if(!b) {
JOptionPane.showMessageDialog(null, "Not Found");
}
您必须改用 PreparedStatement,以避免任何 SQL 注入或语法错误。
ResultSet 的 API 文档解释了 next() 方法:
将光标从其当前位置向前移动一行。一个 结果集光标最初位于第一行之前;这 对方法的第一次调用 next 使第一行成为当前行;这 第二次调用使第二行成为当前行,依此类推。
每次调用 next() 方法时,都会将光标移动到下一行。 这发生在您的代码中(两次):
if (rs.next()) {
while (rs.next()) {
避免此问题的一种方法是使用 first() 之前的方法。 根据 API:
将光标移动到此 ResultSet 对象的前面,紧挨着 第一行。如果结果集不包含 行。
然后,每次在代码"rs.next()"中使用光标时,您都会将光标移动到一个位置(到下一行),但是如果在多次使用 rs.next() 后需要从第一行开始读取,您可以简单地使用 rs.beforeFirst() 并且当您下次调用 rs.next() 时,光标将从结果集的开头开始。
此外,您不需要在代码中使用 if 语句:
if (rs.next()) {
因为使用的时间就足够了。
rs.next()
将增加游标if
因此,如果结果集只有查询返回的一行,那么while
将再次移动游标,并且不会打印任何数据。请改用do..while
循环。
if (rs.next()) {
do {
System.out.print(rs.getString("idUser") + " ,");
System.out.print(rs.getString("Name") + " ,");
System.out.print(rs.getString("Email") + " ,");
System.out.println(rs.getString("country") + " .");
}while (rs.next());
}
感谢每一个答案。我发现放rs.relative(-1)
也可以完成这项工作。但是上面的答案编码得很好,比我的更好。所以谢谢大家。我是编程新手,我会在我的编码中考虑您的所有建议。谢谢
if (rs.next()) {
rs.relative(-1);
while (rs.next()) {
System.out.print(rs.getString("idUser") + " ,");
System.out.print(rs.getString("Name") + " ,");
System.out.print(rs.getString("Email") + " ,");
System.out.println(rs.getString("country") + " .");
}
}
嘿,它跳过了行,因为你在 if 子句中执行 rs.next(),然后在 while 中再次执行。因此,第一次迭代实际上是第二行。最好的选择是如果子句u应该写if(rs.first())