我试图在将本地H2数据库集成到我的JavaFX应用程序(Java8)时避免静态和单例。其他五个类(包括控制器)需要访问数据库,所以我试图共享它们之间的一个H2连接。我已阅读Connection Pool避免不必要的重新连接,但如果它适用于此,则会感到困惑。桌面使用,单用户。跨类访问H2连接
以下ExtrasDB
类包含3种方法,initializeDB
,getDBValues
和performQuery
。以前这些方法是static
,我会从其他类使用ExtrasDB.getDBValues()
调用它们,并相应地使用结果,但由于我的应用程序使用多线程我正在寻找更好的方法。我正在从我的应用中删除所有静态/单身使用的过程。
initializeDB
方法创建连接并根据需要创建一个表,并且从主控制器的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();
}
}
}
'org.h2.test.jdbcx.TestConnectionPool'就是一个例子。 – trashgod
'performQuery(...){executeUpdate(...);嗯......什么?查询数据库会导致更新?也许如果'ResultSet performQuery(){return this.conn.executeQuery(...); }'你实际上不需要共享连接并仍然可以得到结果吗? –
@trashgod,我想花时间理解* [那个例子](https://github.com/pkouki/recsys2015/blob/master/h2/src/test/org/h2/test/jdbcx/TestConnectionPool.java) *,似乎'testKeepOpen()'方法演示了man.dispose()是如何关闭该池的,但是我很困惑:(1)我的类ExtrasDB是否应该是'public static ...'以及3种方法,“公共”还是“私人”?我问的原因是(2)我的其他课程可以使用'ExtrasDb。getDBValues()'(静态),但如果我在每个类中创建一个ExtrasDB对象,它将创建一个新的ConnectionPool。如何分享? – MM88