java - 跨类访问H2连接

标签 java jdbc javafx connection-pooling h2

我试图在集成本地 H2 时避免静态和单例。数据库到我的 JavaFX 应用程序 (Java8)。其他五个类(包括 Controller )需要访问数据库,因此我试图在它们之间共享一个 H2 连接。我读过 Connection Pool避免不必要的重新连接,但如果适用于此,我会感到困惑。桌面使用,单用户。

下面的 ExtrasDB 类包含 3 个方法,initializeDBgetDBValuesperformQuery。以前这些方法是静态的,我会使用ExtrasDB.getDBValues() 从其他类中调用它们并相应地使用结果,但由于我的应用程序使用多线程 我正在寻找更好的方法。我正在从我的应用程序中删除所有静态/单例使用。

initializeDB 方法创建连接并在必要时创建一个表,这个方法只从我的主 Controller 的 initialize 方法调用一次。这会导致连接 conn 与该实例隔离,并且其他类对 getDBValuesperformQuery 的调用无法访问,这会导致空结果集。如何使所有必要的类都可以访问数据库连接,以便这些类可以使用上述方法自由访问数据库?

public class ExtrasDB {

    final String JDBC_DRIVER = "org.h2.Driver";
    final String DB_URL = "jdbc:h2:~/mainDB";
    final String USER = "test";
    final String PASS = "test";
    Connection conn = null;
    Statement statement = null;
    String myStatement;
    ResultSet rs;
    DatabaseMetaData meta;

    public void initializeDB() {

        try {
            Class.forName("org.h2.Driver");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            System.out.println("Connected to database successfully...");
            statement = conn.createStatement();
            meta = conn.getMetaData();
            rs = meta.getTables(null, null, "EXTRAS", new String[]{"TABLE"});  // <--- Checks for existence of table "EXTRAS"

            if (!rs.next()) {

                System.out.println("Table doesn't exist yet... Creating...");
                sql = "CREATE TABLE EXTRAS " +
                        "(column_1 VARCHAR(255), " +
                        " column_2 VARCHAR(255))";

                statement.executeUpdate(sql);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    public void getDBValues() throws SQLException {
        rs = statement.executeQuery("SELECT * FROM EXTRAS");
        while (rs.next()) {
            //..... do something
        }
    }

    public void performQuery(String query) {
        try {
            statement.executeUpdate(query);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

最佳答案

如果您不想要某种静态访问,您有两种选择:

  1. 在您的程序启动时创建一个服务工厂实例(非静态)。 Service-Factory 是一个 pojo 类,包含您希望在其他类之间共享的所有依赖项。这些依赖项可以由 Service-Factory 创建,也可以使用 setter 进行设置。所有需要某些依赖项的类,您只需提供 Factory 实例。
  2. 您可以使用一些实现自动依赖注入(inject)的框架。使用这样的框架,您只需注释您的构造函数或字段。参见 this link有关依赖注入(inject)和 this tutorial 的更多信息关于如何使用spring框架进行依赖注入(inject)。

在我的 JavaFX-App 中,我使用第一个选项。我有一个名为 Root 的类,并在 javafx.application.Application::start 函数中创建了它的一个实例。一些依赖项是由 Root 类创建的,而其他一些依赖项(例如 Controller 实例)是使用 setter 设置的。因为我通过 fxml-loader 加载我的 Controller ,所以我不能使用构造函数来提供 Root 实例,而是每个 Controller 都有一个 init 函数

public void initialize(Root root);

如果您需要更多帮助。请随意评论这个答案。

关于java - 跨类访问H2连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39651627/

相关文章:

java - 为什么 CopyOnWriteArrayList 与迭代不可修改列表不同?

java - 有没有一种方法可以仅使用一种方法对 FXML 文件对象做出不同的响应?

JavaFX用lambda实现call方法的回调

java - 我的 fxgl 遇到非法状态异常 : EntityFactory was not set!

java - 使用 XPath 连接选定子节点的值

java - 即时添加产品以订购

java - 为什么 Properties.list 在打印前复制表格?

java - 带 String/Varchar 参数的 Spring JDBC 模板查询

jdbc - Java DB(Derby)中不区分大小写的搜索

用于管理数据库外部的 BLOB 数据的 Java 框架