java - 将 ResultSet 返回给另一个函数

标签 java jdbc javabeans resultset

我正在创建一个程序来管理 MySQL 服务器。我有一个工作用户界面和代码,可以按预期向数据库添加新条目。下图是我正在使用的原始 GUI,对于这个问题来说重要的部分是表格框,它将在数据库工作时显示数据库的条目。

Text

我用于读取数据库内容的代码可以正常工作。该程序的结构使得我可以为界面、场景 Controller 和 SQL 命令提供单独的类。我正在处理的问题是,我可以从数据库中提取所需的数据,但访问场景 Controller 类以将其写入数据库根本不起作用。

相关代码片段包含在下面。

SQL 函数:

public ResultSet readDataBase() throws Exception{
    try {
        // Establish connection to server
        Class.forName("com.mysql.cj.jdbc.Driver");
        connect=DriverManager.getConnection("jdbc:mysql://localhost/library?"+"user=tempUser&password=12345");
        statement=connect.createStatement();

        // Execute query and write the results
        resultSet=statement.executeQuery("select * from library.books");
        return resultSet;

        // writeResultSet(resultSet);

    } catch (Exception e){
        throw e;
    } finally {
        close();
    }
}

场景 Controller 代码:

public void fillTable() throws SQLException{
    ResultSet resultSet=null;
    try {
        resultSet=commands.readDataBase();

        while(resultSet.next()) {
            String title = resultSet.getString("title");
            String author = resultSet.getString("author");
            String genre = resultSet.getString("genre");
            String format = resultSet.getString("format");
            String isbn = resultSet.getString("isbn");

            System.out.println("Title: " + title);
            System.out.println("Author: " + author);
            System.out.println("Genre: " + genre);
            System.out.println("Format: " + format);
            System.out.println("ISBN: " + isbn);
            System.out.println();
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

场景 Controller block 中代码的目的只是暂时测试并读取结果集。稍后将添加用于将结果中的数据写入各自表的写入代码。选择这段代码是因为我最初将它放在 SQL 函数类中并且它在那里工作,所以我知道这段代码很好并且完成了它的工作。

但是,每当我运行代码时,我都会收到此错误结果。

java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
at com.mysql.cj.jdbc.result.ResultSetImpl.checkClosed(ResultSetImpl.java:445)
at com.mysql.cj.jdbc.result.ResultSetImpl.next(ResultSetImpl.java:1726)
at library.test.windows.interfaceSceneController.fillTable(interfaceSceneController.java:108)
at library.test.windows.winInterface.main(winInterface.java:33)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)

我之前已经对此进行了一些阅读,但我能找到的唯一真正相关的信息来源是在这个 post 中。从七多年前开始。该问题的答案提到使用 JavaBeans 作为将信息放入中间的位置,但随后在示例代码中使用了一个名为“Biler”的类。除了他的帖子之外,我在任何地方都找不到任何对 Biler 的引用,而我的 IDE(IntelliJ,如果相关的话)根本无法识别它。我一直在使用 JavaBeans 进行一些实验,但我不确定它是否能解决我的问题。

总而言之,我的问题是这样的。为了将 ResultSet 从访问 SQL Server 的函数正确传递到包含将其写入界面中的表的代码的类,我需要做什么?我知道这一定有可能,但我似乎无法弄清楚。

最佳答案

您的数据库访问代码应与用户界面代码完全分开。 UI 不应处理 Activity 的 ResultSet

您需要从结果集中复制数据,或使用实用程序来执行此操作。

CachedRowSet

一个RowSet可能是解决方案。该接口(interface)扩展了 ResultSet 。请参阅Java Tutorials Oracle 的解释。

您可以使用CachedRowSet接口(interface)将结果集数据的副本保留在内存中,与数据库分离。 Oracle 提供了一种实现,其他供应商(例如您的 JDBC driver)也可能提供这种实现。 .

CachedRowSet 实现与数据库断开。相反,ResultSet 维护数据库连接(问题的根源)。引用 Javadoc:

A CachedRowSet object is a container for rows of data that caches its rows in memory, which makes it possible to operate without always being connected to its data source. Further, it is a JavaBeans™ component and is scrollable, updatable, and serializable.

该接口(interface)通过更多接口(interface)进行了扩展。

enter image description here

POJO

普通旧 Java 对象是另一种选择,将 ResultSet 中每行的每个字段复制到 Java 对象的属性中。

您可以在实例化记录时简单地循环结果集。或者您可以使用各种框架中的任何一种来提供帮助。

记录

使用 Java 16 中新增的记录功能(现已预览)时,为此类 POJO 定义类要简单得多 in Java 15 。构造函数、getter、toString、equals 和 hashCode 都是由编译器合成的。您只需声明属性即可。

记录可以声明为独立类、嵌套类,甚至可以在方法中本地声明。

关于java - 将 ResultSet 返回给另一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63119694/

相关文章:

java - 我无法从 JDialog 更新 Jcombobox(通过模型)

java - 无法使用 JDBC 连接到 Syabse 数据库

mysql - Spring Security - Bcrypt 与 CAS、MySQL、SearchModeSearchDatabaseAuthenticationHandler 和 BasicDataSource

java - 如何将 XMLEncoder 和 XMLDecoder 与 String 一起使用?

java - CompareTo 的返回结果溢出?

java - 在 Android 中用作嵌套 View 或 RecyclerView 项 View 的自定义 View

java - 如何在 JSP 中的 <%%> 中包含 <HTML>?

java - RabbitMQ 影响 JDBC 连接池

java - 如果输入仅包含 1 和 0,则将其从二进制转换为十进制

java - 如何在使用 jsf 和托管 bean 时将 boolean 字段放入数据表中?