我有一个围绕单服务器数据库构建的 JDBC 应用程序(RDBMS 是 HSQLDB——到目前为止我很喜欢它)。在我的应用程序初稿中,我使用了以下分层方法:
+-------------------------------+
| DATA STORE (appx 20 tables) | HSQLDB; highly normalized tables
+-------------------------------+
|
v
+-------------------------------+
| DOMAIN OBJECT LAYER (1:1) | A Java class for each table in DB
+-------------------------------+
|
v
+-------------------------------+ Abstraction for the objects that the app
| CLIENT OBJECT LAYER / DAO's | logic actually uses (denormalized)
+-------------------------------+
|
V
+-------------------------------+ Adapts ObservableArrayList() instances
| PRESENTATION LAYER (JAVAFX) | of objects to the GUI
+-------------------------------+
在域对象层中,我目前使用通用静态方法执行所有 JDBC 查询:
static <E> ObservableList<E> doGenericQuery(SQLParametersList pars,
String sql, Callback<RowSet,E> factory) {
// factory is a Function Object. For now I use Callback<P,R> as the
// "strategy" ... P is a RowSet, R is the object return type. The factory
// simply invokes the constructor for the desired return object type.
RowSet jrs = null;
ObservableList<E> queryList = FXCollections.<E>observableArrayList();
try {
jrs = SQLConnection.getRowSetInstance();
if (jrs == null) {
System.err.println(Census.MSG_ERR_JDBCFAIL);
return queryList; }
jrs.setCommand(sql);
for(int i=0; i < pars.size(); i++) {
// datum().col() method returns an enum representing the
// database column; setJdbcParamByType is an enum
// constant-specific method that invokes the correct
// setXXX method on the PreparedStatement
pars.datum(i).col().setJdbcParamByType(jrs, pars.datum(i)));
}
jrs.execute();
while (jrs.next()) {
queryList.add(factory.<RowSet,E>call(jrs));
}
} catch (SQLException e) {
Logger.getLogger(DB.class.getName()).log(Level.SEVERE, null, e);
} finally {
if (jrs != null) try { jrs.close(); } catch (SQLException e) { }
}
return queryList;
}
我想做的是在整个应用程序的数据访问抽象中使用此方法,但我想知道是否可以。正如所写,此方法返回一个 ObservableList,因为它由 JavaFX 应用程序使用。 ObservableList 保存 SimpleXXXProperty 对象的实例(JavaFX Bean 样式,即可变对象)。我认为我无法使用目前编写的代码,因为我不想将 JavaFX Bean 样式的对象带到服务器端。
最终,数据访问层将在服务器端环境中执行,而表示层的内容将在客户端上执行。
我真的不想让我的服务器端代码使用 JavaFX Bean 风格的对象。理想情况下,我希望查询形成一个不可变对象(immutable对象)的列表,并且我认为我可以实现这一点,除了需要处理 JavaFX,这似乎要求我将所有内容公开和可变。
我现在想到的解决方案是让服务器代码从查询结果创建不可变对象(immutable对象),这些对象被包装在一个不可修改的列表中,然后传输到客户端。然后,客户端必须将只读列表转换为 JavaFX Bean 样式对象的 ObservableList,以便可以在 GUI 中使用它们。但是..这种方法要求我编写不同版本的域对象层(客户端和服务器)。
我走的路正确吗? (我讨厌听起来好像我有点不知所措,但我现在可能有点不知所措)。
最佳答案
当我更多地思考我想做什么时,我发现我的方法过于简单化。我认为我真正谈论的是从数据存储到客户端的信息流,看起来更接近于此:
+-------------------------------+
| DATA STORE (appx 20 tables) | HSQLDB; highly normalized tables
+-------------------------------+
|
v
+-------------------------------+ Receives query result
| SERVER/SERVLET REQ PROCESSOR | Transmits as CachedRowSet
+-------------------------------+
|
(Serialization)
|
v
+-------------------------------+
| CLIENT INTERFACE LAYER | Deserializes query results
+-------------------------------+
|
v
+-------------------------------+
| DOMAIN OBJECT LAYER (1:1) | A Java class for each table in DB
+-------------------------------+ Generates data model objects from results
|
v
+-------------------------------+ Abstraction for the objects that the app
| CLIENT OBJECT LAYER / DAO's | logic actually uses (denormalized)
+-------------------------------+
|
V
+-------------------------------+ Adapts ObservableArrayList() instances
| PRESENTATION LAYER (JAVAFX) | of objects to the GUI
+-------------------------------+
当然,现在看起来更像是一个基于互联网的客户端服务器应用程序,其框架已经存在,例如。 JavaEE。从简单的单机 JDBC 数据库应用程序到分布式客户端-服务器应用程序似乎涉及复杂性的巨大飞跃。
但是,我认为除了客户端之外,我根本不需要在此过程中的任何地方使用 JavaFX Bean 样式对象。
关于JavaFX 客户端和 JDBC 服务器 : Are JavaFX Bean-style objects required on the server side?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18158048/