我试图在集成本地 H2 时避免静态和单例。数据库到我的 JavaFX 应用程序 (Java8)。其他五个类(包括 Controller )需要访问数据库,因此我试图在它们之间共享一个 H2 连接。我读过 Connection Pool避免不必要的重新连接,但如果适用于此,我会感到困惑。桌面使用,单用户。
下面的 ExtrasDB
类包含 3 个方法,initializeDB
、getDBValues
和 performQuery
。以前这些方法是静态的
,我会使用ExtrasDB.getDBValues()
从其他类中调用它们并相应地使用结果,但由于我的应用程序使用多线程 我正在寻找更好的方法。我正在从我的应用程序中删除所有静态/单例使用。
initializeDB
方法创建连接并在必要时创建一个表,这个方法只从我的主 Controller 的 initialize
方法调用一次。这会导致连接 conn
与该实例隔离,并且其他类对 getDBValues
或 performQuery
的调用无法访问,这会导致空结果集。如何使所有必要的类都可以访问数据库连接,以便这些类可以使用上述方法自由访问数据库?
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();
}
}
}
最佳答案
如果您不想要某种静态访问,您有两种选择:
- 在您的程序启动时创建一个服务工厂实例(非静态)。 Service-Factory 是一个 pojo 类,包含您希望在其他类之间共享的所有依赖项。这些依赖项可以由 Service-Factory 创建,也可以使用 setter 进行设置。所有需要某些依赖项的类,您只需提供 Factory 实例。
- 您可以使用一些实现自动依赖注入(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/