我有以下疑问。当您必须从Java应用程序查询数据库时,有几种方法可以执行此操作。我想出了一些方法,但每个方法都有一个骗局。
第一个是,你有一个班级,例如。 QueryManager
为您提供查询功能,例如executeUpdate(...)
和executeQuery(...)
,同时隐藏连接管理的详细信息等(Facade Pattern的种类)。当您需要与数据库交互时,您将以字符串形式传递查询并管理ResultSet
。
我看到的问题是,如果数据库发生更改,无论是DBMS还是数据库本身,您最终都会按文件修改SQL。我认为这是一个巨大的依赖。此外,您向所有人展示了数据库的结构,并且您正在使每个类处理ResultSet
。另一方面,使用此方法可以实现更高的模块性,因为类的模型(我是 MVC Pattern 的粉丝)可以具有包可见性。
我想到的第二个想法是创建一个QueryManager
类,而不是为您提供查询方法,它将为您提供所需的方法。换句话说,每次需要使用DB时,您将在此类中创建一个方法,其中包含SQL,它将返回您需要的信息。但是,我们在这里面临的问题是,您必须在返回ResultSet
或您需要的数据模型之间进行选择。
前者将使您的类依赖于DB,而不是前面的示例,因为现在没有与DBMS广泛传播的依赖关系,因为所有SQL都包含在一个类/文件中。但是它仍然存在与DB结构的依赖关系,并且您向所有人公开了您的数据库结构
后者暗示theese模型不再是包可见性,它们必须是公共的,允许任何类修改它们,并打破封装。
有没有其他方法可以解决以前的所有问题?如果没有,您认为哪种方法更好?
我认为没有绝对的安装(可能存在),但我必须说我们期待DB的结构和DBMS的变化。这可能对你的衣服有所帮助。但是尽量让它尽可能通用,因为我可能会遇到同样的疑问,但是没有相同的限制。
答案 0 :(得分:2)
我不喜欢你的任何一种方法。
您可以编写一个处理所有内容的接口:通用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);
}
你应该在持久性和模型类之间建立一个清晰的界面;后者无需了解前者。
您不应允许ResultSet
或Statement
泄露出持久层。
您应该拥有一个获取连接和管理事务的服务层。
您应该以这样的方式编写SQL:切换数据库 - 这应该很少发生 - 就像更改JDBC驱动程序JAR和连接参数一样简单。
答案 1 :(得分:2)
第二个是好的:您应该在数据访问对象(DAO)中提取数据访问方法,这样可以将应用程序的其余部分与持久性相关的问题隔离开来。 DAO肯定应该返回对象,而不是结果集。
这提供了以下优点:
答案 2 :(得分:0)
我建议为所有实体创建DAO类(http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html),这将隐藏SQL / HQL /内部的任何内容。它们将返回对象模型,因此业务逻辑类不关心从数据库/等中查询/获取。
答案 3 :(得分:0)
我认为你所追求的是data access object(DAO)模式。如果你使用像Hibernate之类的对象关系映射的框架,你的DAO实际上可以specify the database schema directly(我认为它非常整洁)。否则,通常会提供一组手动滚动的DAO类,它们抽象出所有底层数据库问题(例如,DAO类不应返回ResultSet)。
答案 4 :(得分:0)
我认为我们必须使用两种方法进行查找:可更新数据库和只读数据库。
如果你想在你的数据库中插入/更新/删除一些东西,我认为没有任何方法可以在没有你的数据库知识的情况下实现这个目的:名称,数据类型......
但是,另一方面,如果您只是想在数据库中进行搜索,那么有一种很好的方法可以实现这一目标:使用数据库视图。您可以拥有大量视图,并且每个视图都包含您需要的所有数据,但是没有人需要确切知道视图背后的数据。您可以限制某些用户只能看到视图,而不是原始表,因此您可以“隐藏”您的真实数据库结构。
我认为这不仅仅是Java方法:它是数据库+ Java方法。