设计保存在数据库中的对象是否有普遍接受的做法?

时间:2010-07-27 02:10:56

标签: java database

是否有一种普遍接受的做法来设计经常加载和保存到数据库中的Java对象?

我现在使用的方法是有一个主数据库对象,它打开与数据库的连接。在我的应用程序中我需要加载或保存对象的任何地方,我创建了一个用于加载和保存的源接口。例如,我可能会这样做:

public interface CalendarSource {
  public Appointment[] getAppointmentsForMonth(int year, int month);
  public void saveAppointment(Appointment appointment);
}

然后我将在主数据库对象上实现该接口。任何子数据也会同时加载到主对象内的成员对象中。就像每个约会的客人名单一样。这很好用,因为我使用的所有数据都来自两个数据库中的一个,因此我保留了两个数据库连接,每个源都由其中一个实现。

问题在于,这有时似乎很笨拙。令人困惑的是如何处理ID值,因为我真的不想将它们添加到我的对象中。它还需要一个数据库连接来实现几个不同的接口。实际上,我的数据库包必须依赖于项目中的几乎每个包,因为它实现了所有接口。这在某个层面上确实有意义,但我想知道是否有更好的方法。

我选择这种架构有两个主要原因:

  • 我希望我使用的对象不知道它们是从数据库加载或保存的。我可能希望将来使用平面文件替换此数据库源以实现可移植性。
  • 我想要一个好的包依赖层次结构。应隔离数据库代码,以便可以轻松地将对数据库模式的更改更新为代码。

我遇到的一个问题是如何处理ID值。由于对象不应该知道它们是数据库对象,因此它们不应该包含ID字段。但是,如果我尝试将对象写入数据库,并且我没有ID值,那么我应该知道是否应该进行插入或更新?

我还担心让数据库包扩展整个项目的所有内容。我经常传递这些源接口。我想这也是有道理的。

也许我只是在寻找一些我做得对的验证,而且我没有看到一些明显的简单解决方案。不要误会我的意思 - 一切正常。

有什么想法吗?

4 个答案:

答案 0 :(得分:5)

我认为最普遍的模式是DAO模式。也就是数据访问对象。基本上,您定义了一个指定行为的接口(如基本的crud操作和域的专用行为),然后提供实现。对于额外的点,你可以使用泛型是java 5或更高版本来编写更少的代码。

http://www.ibm.com/developerworks/java/library/j-genericdao.html

将所有持久性代码保存在应用程序的一个层中是一个重要的设计选择。它有助于保持代码简单和干净。

从你的帖子中,你不想做你正在做的事情。使用Spring或等价物,因为它会为你处理很多代码。它管理连接,交易等。

另外,不要担心课程上有ID字段。虽然你可能不认为它是完美的,但它会让生活更轻松。选择对抗较大的设计战斗,例如做TDD并保持设计清洁。

答案 1 :(得分:2)

不要自己动手。

看看Hibernate,iBatis和JPA。

抛硬币。 (我喜欢iBatis,但其他两个同样好)

完全采用所选技术。

既然你已经实施了某些东西,那么你已经学会了这项技术,现在可以做出理性的选择来寻求替代方案或坚持你最初选择的方法。

重要提示:不要自己动手。

答案 2 :(得分:2)

您的方法前进'一个中央数据库对象'和'子数据也被加载'似乎是良好设计的方向。

然而,由于这是2010年的Java,数据存储等问题以及所有相关的问题都已经实现。你有更多的规范,如JDBC,JPA和JDO,对于这些规范,有几个实现,如Hibernate,Open JPA,EclipseLink ......

E.g。 JPA和Hibernate是一个完美的选择!您需要一个xml配置文件来定义数据库配置(http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html)。

您可以在该xml(http://docs.jboss.org/hibernate/core/3.3/reference/en/html/xml.html)中或通过注释(http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/)定义持久Java类 - 数据库表映射。

您将使用Hibernate Session / Entity管理器将持久性对象状态保存到表中。 (http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html_single/

对于Id值:在大多数情况下会生成这些值,有几种可能的值生成方法。(http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-id

您可以保持独立于数据库表,您可以随时重新构建,重命名,因为这些可以重新配置。对于更复杂的更改,您应该检查(http://docs.jboss.org/hibernate/stable/core/reference/en/html/inheritance.html

如果您更改为文件存储,没有问题,因为您的Java类是可序列化的类,您可以随时将其状态保存到独立于数据库实现的文件中。(http://java.sun.com/developer/technicalArticles/Programming/serialization/

Java World Hibernate Tutorial

答案 3 :(得分:1)

我说最简单的结构通常类似于

创建包含所需字段的域对象。

Public class Appointment {
private Date appointmentDate;
private String locationName;
List<Person> appointmentAttendees;
}

然后你有一个数据库,它将1个字段映射到1个列......然后将它放在Hibernate中,从对象到数据库对象来回传递。

这会满足您的所有需求吗?谁知道。取决于你所需要的一切:P