我一直在使用JDBC和不同类型的ResultSet,并且有一个关于使它成为TYPE_SCROLL_SENSITIVE的问题(这个问题与敏感部分有关,而不是类型滚动部分)。该理论认为数据库中的更改会反映在ResultSet中,反之亦然,但这种情况并非发生在我身上。
这是我尝试过的东西:
Connection conn = null;
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
String url = "jdbc:oracle:thin:@oracle.myCompany.com:1521:xe";
conn = DriverManager.getConnection(url, "username", "password");
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT user_id, first_name, last_name FROM Users";
ResultSet rs = stmt.executeQuery(query);
while(rs.next()){
System.out.println("-----------------------------");
System.out.println(rs.getInt(1));
System.out.println(rs.getString("first_name"));
System.out.println(rs.getString("last_name"));
int id = rs.getInt(1);
rs.updateInt(1,100+id);
}
} catch (SQLException e) {
e.printStackTrace();
} finally{
conn.close();
}
当我更新ID,向其添加100时,更改未显示在数据库中(如果在此下面,我添加了rs.updateRow(),那么它确实更新了数据库。但是这也会更新数据库我把它变成TYPE_SCROLL_INSENSITIVE)。
我尝试过的另一件事是:
Connection conn = null;
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
String url = "jdbc:oracle:thin:@oracle.myCompany.com:1521:xe";
conn = DriverManager.getConnection(url, "username", "password");
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT user_id, first_name, last_name FROM Users";
ResultSet rs = stmt.executeQuery(query);
String query2 = "INSERT INTO User VALUES (4, 'Joe', 'Bloggs')";
stmt.executeUpdate(query2);
while(rs.next()){
System.out.println("-----------------------------");
System.out.println(rs.getInt(1));
System.out.println(rs.getString("first_name"));
System.out.println(rs.getString("last_name"));
int id = rs.getInt(1);
rs.updateInt(1,100+id);
}
} catch (SQLException e) {
e.printStackTrace();
} finally{
conn.close();
}
但是如果我运行这段代码,并期望新行在resultSet中,因为它是敏感的...我在行上得到一个NullPointerException:while(rs.next()){
那么有人可以解释一下敏感的ResultSet如何工作以及我做错了什么?可能有一个例子吗?
答案 0 :(得分:3)
TYPE_SCROLL_SENSITIVE意味着如果在迭代数据时对表进行了更改,您将看到它。要重现此行为,请暂停
System.out.println("-----------------------------");
使用外部工具更改first_name,然后执行此行
System.out.println(rs.getString("first_name"));
变化应该是可见的。
请注意,此功能是可选的。要测试它是否已启用,请运行此
boolean res = conn.getMetaData().ownDeletesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE);
System.out.println(res);
答案 1 :(得分:1)
对您使用updateInt
执行的字段的所有更新都需要调用updateRow
才能生效。这与滚动类型无关。根据特定的数据库,您甚至可以更新ResultSet
TYPE_FORWARD_ONLY
(如果支持,它是最快的替代方案)。唯一的限制是,它们必须是CONCUR_UPDATABLE
。
第二个代码的错误是使用与获取ResultSet
时相同的更新语句。因此,执行更新时ResultSet
将变为无效。你必须使用两个语句。
更改
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT user_id, first_name, last_name FROM Users";
ResultSet rs = stmt.executeQuery(query); // you use stmt here
String query2 = "INSERT INTO User VALUES (4, 'Joe', 'Bloggs')";
stmt.executeUpdate(query2); // here you use stmt again
到
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT user_id, first_name, last_name FROM Users";
ResultSet rs = stmt.executeQuery(query);
Statement stmt2 = conn.createStatement();// new statement for the insertion
String query2 = "INSERT INTO User VALUES (4, 'Joe', 'Bloggs')";
stmt2.executeUpdate(query2);
答案 2 :(得分:0)
在从resultset对象迭代数据以查看更改时,首先需要停止程序执行一段时间才可以使用System.in.read(),之后你可以转到数据库更改表数据并转到程序,以查看结果集中更新的行,您在结果集对象上使用refreshrow()。 您可以使用refreshrow()方法将更新的行数据从数据库获取到结果集。
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT user_id, first_name, last_name FROM Users";
ResultSet rs = stmt.executeQuery(query); // you use stmt here
while(rs.next()){
System.out.println("-----------------------------");
System.in.read();
System.out.println(rs.getInt(1));
rs.refreshRow();
System.out.println(rs.getString("first_name"));
System.out.println(rs.getString("last_name"));
}