好的,我有一段被调用了多次的代码。然而,在一些测试过程中,我注意到根据数据库,我的 ResultSet 返回错误。经过进一步调查,我注意到它以某种方式被重用。值得一提的是,当我重新启动程序时,它会获取正确的结果。 SQL 始终相同。
我的代码:
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1, packet.getUserId());
ResultSet dbResult = ps.executeQuery();
while(dbResult.next())
{
System.out.println("There were items!" );
Item item = new Item();
item.setItemType(dbResult.getInt(1));
item.setFromUser(dbResult.getString(2));
item.setItemMessage(dbResult.getString(3));
toReturn.add(item);
}
这是我的测试顺序:
- 从 ResultSet 中获取行一次并获得正确的结果 - 好的
- 从表中删除上述特定 SQL 使用的所有行,这意味着 ResultSet 下次不应返回任何内容。
- 尝试再次提取(现在应该返回 0 行),但它会返回与步骤 1 中完全相同的行,即使数据库表为空。
结果集是否应该在使用后关闭或进行其他操作,或者我缺少什么? 即使数据库中没有任何内容,我也从 ResultSet 中获取结果。我可以保证 SQL 是合法的,但 ResultSet 似乎不是在第二次调用时从中创建的。
编辑(连接初始化代码)
public class DBFactory
{
protected String databaseName = null;
protected String username = null;
protected String password = null;
protected Connection connection = null;
protected Statement statement = null;
protected DBFactory( String databaseName, String username, String password)
{
this.databaseName = databaseName;
this.username = username;
this.password = password;
}
protected void initConnection()
{
if (databaseName == null || username == null || password == null)
throw new IllegalStateException();
try
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
this.connection = DriverManager.getConnection(this.databaseName, this.username, this.password);
this.statement = this.connection.createStatement();
}
catch (Exception e)
{
System.out.println("DBFactory " + e.getMessage());
}
}
最佳答案
我希望您已关闭连接的自动提交。
据我了解您的问题,这个小代码示例将演示它。
package org.yi.happy.mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class RepeatQuery {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver").newInstance();
setupDatabase();
System.out.println("opening database...");
Connection connection = openConnection();
connection.setAutoCommit(false);
queryDatabase(connection);
deleteRecords();
queryDatabase(connection);
connection.close();
}
private static Connection openConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost/test", null,
null);
}
private static void setupDatabase() throws SQLException {
Connection conn = openConnection();
System.out.println("doing insert on another connection...");
PreparedStatement stmt = conn
.prepareStatement("insert into strings(id, value) values(?, ?)");
stmt.setInt(1, 1);
stmt.setString(2, "test");
stmt.execute();
stmt.setInt(1, 2);
stmt.setString(2, "data");
stmt.execute();
stmt.close();
conn.close();
}
private static void deleteRecords() throws SQLException {
Connection conn = openConnection();
System.out.println("doing delete on another connection...");
PreparedStatement stmt = conn.prepareStatement("delete from strings");
stmt.execute();
stmt.close();
conn.close();
}
private static void queryDatabase(Connection connection)
throws SQLException {
System.out.println("doing query...");
PreparedStatement ps = connection
.prepareStatement("select id, value from strings");
ResultSet dbResult = ps.executeQuery();
while (dbResult.next()) {
int id = dbResult.getInt(1);
String value = dbResult.getString(2);
System.out.println(id + " <=> " + value);
}
}
}
上面的输出是
doing insert on another connection...
opening database...
doing query...
2 <=> data
1 <=> test
doing delete on another connection...
doing query...
2 <=> data
1 <=> test
如果我改变
connection.setAutoCommit(false);
阅读
connection.setAutoCommit(true);
输出变为
doing insert on another connection...
opening database...
doing query...
2 <=> data
1 <=> test
doing delete on another connection...
doing query...
这似乎是您所期望的。
关于java - 结果集被重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13888209/