gpt4 book ai didi

java - MySQL 结果集可滚动/可更新未按预期工作

转载 作者:行者123 更新时间:2023-11-29 15:44:22 27 4
gpt4 key购买 nike

我有一个测试 JDBC 程序,它尝试更改 ResultSet 的可滚动性和可更新性功能。不幸的是,TYPE_CONCUR_ 的所有组合似乎都会产生相同的结果(TYPE_SCROLL_INSENSITIVECONCUR_READ_ONLY)。

即使使用默认值(TYPE_FORWARD_ONLY),也可以滚动结果集。谁能解释一下这是为什么?

我使用的是 MySQL 5.6 和 JDK7。这是代码:

public class ResultSetTest3 {

public static void main(String[] args)
{
Connection conn;

try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/bd", "user", "password");

Statement sta = conn.createStatement();
sta.execute("DELETE FROM test");
sta.close();

PreparedStatement ps = conn.prepareStatement("INSERT INTO test VALUES(?, ?)");
for(int i=1; i<=100; i++)
{
ps.setInt(1, i);
ps.setString(2, "Teste " + i);
ps.addBatch();
}
ps.executeBatch();
ps.close();

System.out.println("TYPE_FORWARD_ONLY CONCUR_READ_ONLY");
result(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
System.out.println("===================================");

System.out.println("TYPE_SCROLL_INSENSITIVE CONCUR_READ_ONLY");
result(conn, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
System.out.println("===================================");

System.out.println("TYPE_SCROLL_SENSITIVE CONCUR_READ_ONLY");
result(conn, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
System.out.println("===================================");

System.out.println("TYPE_FORWARD_ONLY CONCUR_UPDATABLE");
result(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
System.out.println("===================================");

System.out.println("TYPE_SCROLL_INSENSITIVE CONCUR_UPDATABLE");
result(conn, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
System.out.println("===================================");

System.out.println("TYPE_SCROLL_SENSITIVE CONCUR_UPDATABLE");
result(conn, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
System.out.println("===================================");

conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

private static void result(Connection conn, int type, int update) throws SQLException
{
Statement sta = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = sta.executeQuery("SELECT * FROM test");

System.out.println(rs.getConcurrency() + " " + update);
System.out.println(rs.getType() + " " + type);

try
{
rs.absolute(10);
System.out.println(rs.getInt(1) + " - " + rs.getString(2));

rs.relative(20);
System.out.println(rs.getInt(1) + " - " + rs.getString(2));

rs.previous();
System.out.println(rs.getInt(1) + " - " + rs.getString(2));

rs.first();
System.out.println(rs.getInt(1) + " - " + rs.getString(2));

try {
System.out.println("AGORA!!!");
Thread.sleep(20000);
} catch (Exception e) {
System.out.println(e);
}
rs.absolute(3);
System.out.println(rs.getInt(1) + " - " + rs.getString(2));
}
catch(SQLException e)
{
System.out.println("Not Scrollable");
}

try
{
rs.next();
rs.next();
rs.next();
rs.next();

rs.deleteRow();

rs.next();
rs.updateString(2, "TesteUpdate");

rs.insertRow();
}
catch(SQLException e)
{
System.out.println("Not Updatable");
}

rs.close();
sta.close();
}
}

最佳答案

正如 Mark Rotteveel 在对该问题的评论中提到的那样,MySQL 默认情况下会缓存 ResultSet 数据(也在博客文章中进行了讨论)本·克里斯滕森 here )。这种缓存的一个明显的副作用是 MySQL Connector/J 会将 TYPE_FORWARD_ONLY 结果集“升级”为实际上可滚动的:

Statement s = dbConnection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = s.executeQuery("SELECT * FROM testdata");
rs.last();
System.out.println(String.format("Current row number: %d", rs.getRow()));
rs.previous();
System.out.println(String.format("Current row number: %d", rs.getRow()));

显示

Current row number: 3
Current row number: 2

根据上面引用的博客文章,防止缓存和“流”ResultSet 数据的方法是使用 Statement.setFetchSize:

Statement s = dbConnection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
ResultSet rs = s.executeQuery("SELECT * FROM testdata");
rs.next();
System.out.println("Data from first row: " + rs.getString(2));
System.out.println("now let's try rs.last() ...");
try {
rs.last();
System.out.println("... Okay, done.");
} catch (Exception e) {
System.out.println("... Exception: " + e.getMessage());
}

结果

Data from first row: Gord
now let's try rs.last() ...
... Exception: Operation not supported for streaming result sets

关于java - MySQL 结果集可滚动/可更新未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57230994/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com