CachedRowSet 和 SQLite JDBC 驱动程序

Posted

技术标签:

【中文标题】CachedRowSet 和 SQLite JDBC 驱动程序【英文标题】:CachedRowSet and SQLite JDBC driver 【发布时间】:2017-05-13 18:41:54 【问题描述】:

我正在尝试将 CachedRowSet 与 SQLite 和 Xerial 驱动程序 https://bitbucket.org/xerial/sqlite-jdbc 一起使用。

如果我这样调用 execute() 方法:

  Connection connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
  CachedRowSet crs = new CachedRowSetImpl();
  crs.setCommand("select * from person");
  crs.execute(connection);

我收到“SQLite JDBC 驱动程序未实现”的 SQLException:

    at com.sun.rowset.internal.CachedRowSetReader.readData(Unknown Source)
    at com.sun.rowset.CachedRowSetImpl.execute(Unknown Source)
    at com.sun.rowset.CachedRowSetImpl.execute(Unknown Source)
    at com.oracle.tutorial.jdbc.CachedRowSetSample.testPaging(CachedRowSetSample.java:100)
    at com.oracle.tutorial.jdbc.CachedRowSetSample.main(CachedRowSetSample.java:273)

另一方面 ResultSet 和 populate() 而不是 excecute() 工作正常:

  Connection connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
  statement = connection.createStatement();
  ResultSet rs = statement.executeQuery("select * from person");
  CachedRowSet crs = new CachedRowSetImpl();
  crs.populate(rs);

有人知道execute()有什么问题吗?

【问题讨论】:

请发布完整的异常堆栈跟踪。另外:你为什么要使用CachedRowSet,在我看来它相当有问题,而且很少有用。 上述异常来自 oracle 示例,我已经减少了编码,这里是完整的异常,但我认为没有新信息:Exception in thread "main" java.sql.SQLException: not implemented by SQLite JDBC driver at com.sun.rowset.internal.CachedRowSetReader.readData(Unknown Source) at com.sun.rowset.CachedRowSetImpl.execute(Unknown Source) at First.rowSet1(First.java:33) at First.main(First.java:79) 我预计会出现异常原因,其中包括在 SQLite 驱动程序中调用了哪个方法,该方法实际抛出“未由 SQLite JDBC 驱动程序实现”,但查看 CachedRowSetReader 中的实际代码会抛出一个带有初始异常消息但未设置异常原因的新异常...正如我所说:在我看来,它有很多错误,而且很少有用。 非常感谢您的回答,您推荐哪个本地实现断开连接的 RowSet? 我认为这个问题可能是特定于 SQLite,oracle 的教程适用于 mysql。通过建立与 SQLite 的连接,某些选项可能很重要? 【参考方案1】:

不幸的是,在使用 SQLite 时,您必须实现一些 JDBC 函数。这恰好是其中之一。可能最好的替代解决方案是将整个结果集放入 List 并使用它:

// Variables. 
final int TIMEOUT_DEFAULT=30;
String query = "select * from person";
ResultSet rs;
Statement statement;
List<String[]> people;

...

// Create query and execute. (Connection established, database open.)
try                 
    statement = connection.createStatement();
    statement.setQueryTimeout(TIMEOUT_DEFAULT);
    connection.setAutoCommit(true);
    rs = statement.executeQuery(query);  
 catch (SQLException e) 
    // If error, close connection & ignore close errors.
    try  connection.close();  
        catch (SQLException e2)  /* Ignore */ 
    // Throw new error.
    throw new SQLException("Query failed",e);


// Retrieve results.
try 
    people = new ArrayList<>();
    while (rs.next()) 
        people.add(new String[]
            rs.getString(1), rs.getString(2), rs.getString(3)
        );
    
 catch (SQLException e) 
    // If error, close connection & ignore close errors.
    try  connection.close();  
        catch (SQLException e2)  /* Ignore */ 
    // Throw new error.
    throw new SQLException("Error retrieving data",e);


// Close connection, ignore error.
try  
    connection.close(); 
 catch (SQLException e)  /* Ignore */ 

// Print output.
for (String[] p : people) 
    System.out.println(Arrays.deepToString(p));

this post 中的答案包含有关在您的驱动程序不支持的情况下模拟功能的评论。

【讨论】:

以上是关于CachedRowSet 和 SQLite JDBC 驱动程序的主要内容,如果未能解决你的问题,请参考以下文章

CachedRowSet、ResultSetDynaClass 还是其他集合?

getBytes() 使用 ResultSet 但不使用 CachedRowSet

当我使用 DefaultTableModel 从 CachedRowSet 填充 jTable 时,为啥 JTable 的列标题没有更新?

哪些步骤可以使用 Spring-Boot 和 JPA 启用 SQLite?

jdbc 行集在哪里使用?

使用 jdb 调试 Java servlet。如何将 jdb 与 Tomcat 连接