jdbc resultset with mysql忽略resultset类型

f5emj3cl  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(260)

我试图在java应用程序中处理大量的数据。数据存储在mysql数据库中,我使用的是jdbc connector 8.0.11。
我的问题是,我需要多次访问每条记录,再次执行查询需要花费太多时间。使用 ResultSet.absolute(1) 抛出一个异常,说明游标仅为类型\u forward\u。
如本文所述,应该使用参数创建一个语句 ResultSet.TYPE_SCROLL_INSENSITIVE 以及 ResultSet.CONCUR_READ_ONLY 参数以获得具有滚动能力的结果集。
但是我的孩子 ResultSet 总是 ResultSet.TYPE_FORWARD_ONLY ,忽略create语句方法中提供的任何参数。
在官方的mysql网站上,我没有找到任何解释或信息,如果这个功能是支持的。
对于测试用例,我编写了以下代码来检查其他组合是否会影响 ResultSet 类型和总是得到 TYPE_FORWARD_ONLY .

Connection conn = Database.getConnection();
    Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll sensitive, is forward only");
    }
    st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll insensitive, is forward only");
    }
    st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll insensitive, is forward only");
    }
    st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll sensitive, is forward only");
    }
    st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll sensitive, is forward only");
    }
    st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE,ResultSet.HOLD_CURSORS_OVER_COMMIT);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll insensitive, is forward only");
    }
    st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY,ResultSet.HOLD_CURSORS_OVER_COMMIT);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll insensitive, is forward only");
    }
    st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE,ResultSet.HOLD_CURSORS_OVER_COMMIT);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll sensitive, is forward only");
    }       
    st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY,ResultSet.HOLD_CURSORS_OVER_COMMIT);
    if(st.getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) {
        System.out.println("Should be scroll sensitive, is forward only");
    }

下面是一段代码片段,解释如何创建数据库连接:

private static final String driverName = "com.mysql.cj.jdbc.Driver";

    com.mysql.cj.jdbc.Driver dr = (com.mysql.cj.jdbc.Driver) Class.forName(driverName).newInstance();

    MysqlDataSource src = new MysqlDataSource();
    src.setUseCursorFetch(true);        
    src.setServerName("localhost");     
    src.setPort(port);
    src.setDatabaseName("dbname");
    src.setUseSSL(false);
    src.setUser(dbUser);
    src.setPassword(dbPass);
    src.setServerTimezone("GMT+2");
    conn = src.getConnection(dbUser, dbPass);

所以我想问:
为什么我的 ResultSet 总是 TYPE_FORWARD_ONLY ?
有没有办法改变这种行为?

8gsdolmq

8gsdolmq1#

jdbc ResultSet 在语义上类似于数据库游标,但并非所有数据库系统(包括mysql)都支持游标(见下文)。如果 TYPE_SCROLL_SENSITIVE 或者 TYPE_SCROLL_INSENSITIVE 这通常意味着jdbc驱动程序以支持可滚动游标的数据库为目标。当然,jdbc驱动程序仍然可以通过缓存结果集来模拟这种行为,但大多数驱动程序不这样做。
来自mysql文档((src:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-implementation-notes.html)
mysql不支持sql游标,jdbc驱动程序也不模拟它们,因此setcursorname()没有任何效果。
mysql的新版本部分支持游标(http://www.mysqltutorial.org/mysql-cursor/ )但它们仍然不能滚动。
因此,要做你想做的事,只需缓存结果集(例如,将其存储在哈希Map或其他容器中),并在需要时检索特定的记录。

相关问题