1

我有以下疑问。当您必须从 Java 应用程序查询数据库时,有几种方法可以做到这一点。我想出了一些方法,但每个方法都有一个缺点。

第一个是,你有一个类,例如。QueryManager它为您提供查询功能,例如executeUpdate(...)隐藏executeQuery(...)连接管理的详细信息等(一种外观模式)。当您需要与数据库交互时,您会将查询作为字符串传递并管理ResultSet.

我看到的问题是,如果数据库发生变化,无论是 DBMS 还是数据库本身,您最终都会一个接一个地修改 SQL。我认为这是一个巨大的依赖。此外,您正在向所有人展示您的数据库的结构,并且您正在让每个班级都处理ResultSet. 另一方面,您可以通过使用此方法实现更高的模块化,因为您的类的模型(我是MVC 模式的粉丝)可以具有包可见性。

我想到的第二个想法是创建一个QueryManager类,它不会为您提供查询方法,而是为您提供所需的方法。换句话说,每次你需要使用数据库时,你都会在这个类中创建一个方法,里面有SQL,它会返回你需要的信息。但是,我们在这里面临的问题是,您必须在返回ResultSet所需数据的一个或一个模型之间做出选择。
前者将使您的类对 DB 的依赖比在前面的示例中要少,因为现在与 DBMS 没有广泛传播的依赖关系,因为所有 SQL 都包含在一个类/文件中。但是,它仍然存在与 DB 结构的依赖关系,并且您也在向所有人公开您的 DB 结构。
后者意味着这些模型不再是包可见性,它们必须是公共的,允许任何类修改它们,并破坏封装。

有没有其他方法可以解决所有以前的问题?如果不是,您认为哪种方法更好?

我不认为有绝对的答案(也许有),但我必须说,我们期待 DB 的结构和 DBMS 的结构发生变化。这可能有助于您的回答。但是尽量让它尽可能通用,因为我可能在其他项目中也有同样的疑问,但没有同样的限制。

4

5 回答 5

1

我不喜欢你的任何一种方法。

您可以编写一个处理所有这些的单一接口:通用 DAO。这是一个简单的示例,它并不打算成为完整的答案,因为它不允许临时查询或映射到任意对象,但它是一个开始:

public interface GenericDao<K, V> {
    List<V> find();
    V find(K key);
    K save(V value);
    void update(V value);
    void delete(V value);
}

您应该在持久性和模型类之间有一个清晰的接口;后者不必知道前者。

您不应该允许ResultSetStatement泄漏出持久层。

您应该有一个获取连接和管理事务的服务层。

您应该以这样一种方式编写 SQL,即切换数据库(如果有的话应该很少发生)就像更改 JDBC 驱动程序 JAR 和连接参数一样简单。

于 2012-06-04T14:42:02.710 回答
1

第二个很好:您应该在数据访问对象 (DAO) 中提取您的数据访问方法,它将应用程序的其余部分与持久性相关的问题隔离开来。而且 DAO 绝对应该返回对象,而不是结果集。

这提供了以下优点:

  • 关注点和责任的脱钩
  • 当架构改变时,应用程序的其余部分更容易演变
  • 当您选择使用 ORM 而不是 JDBC 访问数据库时,应用程序的其余部分更容易演变
  • 更容易对查询(以及一般的持久层)进行单元测试,因为持久性代码没有与功能代码混合
  • 业务(服务)层的单元测试更容易,因为它允许注入模拟 DAO 来提供数据,而不是需要数据库中的真实数据来测试它。
于 2012-06-04T14:43:45.797 回答
0

我建议为所有实体创建 DAO 类(http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html),这将隐藏 SQL/HQL/里面的任何东西。它们将返回对象模型,因此业务逻辑类将不关心查询/从数据库/等中获取。

于 2012-06-04T14:40:10.573 回答
0

我认为您所追求的是数据访问对象(DAO) 模式。如果您使用像Hibernate这样的对象关系映射框架,您的 DAO 实际上可以直接指定数据库模式(我认为这非常简洁)。否则,通常会提供一组手工制作的 DAO 类,这些类抽象出所有底层数据库关注点(例如,DAO 类不应返回 ResultSet)。

于 2012-06-04T14:43:30.977 回答
0

我认为我们必须使用两种方法进行查找:可更新数据库和只读数据库。

如果您想在数据库中插入/更新/删除某些内容,我认为如果不了解您的数据库如何:名称、数据类型......

但是,另一方面,如果您只想在数据库中搜索,有一个很好的方法可以实现这一点:使用数据库视图。您可以有很多视图,每个视图都包含您需要的所有数据,但没有人需要确切知道视图背后有哪些数据。您可以限制某些用户只能看到视图,而不是原始表,因此您可以“隐藏”您的真实数据库结构。

我认为这不仅仅是 Java 方法:它是一种数据库 + java 方法。

于 2012-06-04T14:45:02.037 回答