【问题标题】:What is the best way of relating relational database tables into Java classes?将关系数据库表关联到 Java 类的最佳方法是什么?
【发布时间】:2009-04-21 12:42:48
【问题描述】:

我想知道是否有人可以在这里给我建议;我有一个应用程序,它有这样的类:

代码:

public class Order implements Serializable { 
    private int orderNo; 
    private int customerNo;    
    private date orderDate; 

    public int getOrderNo () { 
        return orderNo; 
    } 

    public int getCustomerNo () { 
        return customerNo; 
    } 

    public date getOrderDate () { 
        return orderDate; 
    } 

    // And so on with set methods. 

} 

public class OrderLine implements Serializable { 
    private int orderNo; 
    private int lineNo;    
    private int qty; 
    private int prodID; 

    // Get and set methods for each of the above. 
    public int getOrderNo () { 
        return orderNo; 
    } 

    public int getLineNo () { 
        return lineNo; 
    } 

    public int getQty () { 
        return qty; 
    } 

    public int prodID () { 
        return prodID; 
    } 
    // And so on with set methods. 
}

这直接转化为关系表:

订单:orderno、customerNo、orderDate OrderLine: orderno, lineNo, qty, prodID

因此,每个类都直接转换为一个数据库表,其中每个属性都有 get 和 set 对。

现在我想知道的是,如果在 Java Web 应用程序中,类应该是上面的还是更像这样,其中获取返回对象:

代码:

public class Order implements Serializable { 
    private int orderNo; 
    private Customer;    
    private date orderDate; 
    private ArrayList<OrderLine>lineItems; 

    public int getOrderNo () { 
        return orderNo; 
    } 

    public Customer getCustomer () { 
        return Customer; 
    } 

    public date getOrderDate () { 
        return orderDate; 
    } 

    public ArrayList<OrderLine> getOrderLines () { 
        return lineItems; 
    } 

    public OrderLine[] getOrderLines () { 
        return lineItems; 
    } 
    // And so on with set methods.     
} 

public class OrderLine implements Serializable { 
    private int orderNo; 
    private int lineNo;    
    private int qty; 
    private Product; 

    // Get and set methods for each of the above. 

    public int getOrderNo () { 
        return orderNo; 
    } 

    public int getLineNo () { 
        return lineNo; 
    } 

    public int getQty () { 
        return qty; 
    } 

    public int getProduct () { 
        return Product; 
    } 
}

哪种方法更好?或者,只要处理数据的类正确执行并且系统高效运行,采用哪种方法真的很重要吗?

谢谢

摩根先生

【问题讨论】:

  • 你看过像 Hibernate 这样的 ORM 吗?
  • 系统使用 NetBeans 和 Java JSP / servlet 代码库和 MySQL 后端数据库,通过 Apache Server 作为 Web 服务器。
  • +1 回答:每个提到 ORM 映射器的人,尤其是 Hibernate。根据我的说法,这是要走的路!就是这么简单明了! =P

标签: java database class relational


【解决方案1】:

绝对没有理由使用第一种形式 - 在 Java 代码中使用它会更加困难,并且会因此产生很多错误。

所有体面的 O/R 映射器(Hibernate 是最流行的映射器)都可以毫无问题地从 DB 模式转换为适当的 OO 对象图。

但是,不利的一面是,为您完成所有这些操作可能会导致 very bad performance 当您将所有内容留给 OR 映射器并且它从数据库中获取太多或太少的数据时,因此您必须注意缓存以及您的收藏是否为lazy or eager loading

【讨论】:

  • 但是如果第一个表单已经被使用并且当前工作正常并且没有已知的错误怎么办?离开它还是重新设计它更好?当前系统有一组数据库访问类,例如要获取订单行,调用一个以订单号为参数的方法。
  • 如果当前系统很大,运行良好,并且您不打算进行重大更改,那么最好保持原样。如果它很小并且你知道你必须大幅扩展它,我会花时间改用 OR 问题。
  • 大约 25 个核心表,其中包含许多动态创建的表,这些表具有不同的列类型,因此这些表不会计算在内。但是可能有 25 张桌子。
  • 我将其归类为“中等规模”,所以这主要取决于还有多少进一步的开发工作。
  • 作为一个正在进行的项目很难说。当前的数据访问层工作得很好,并且无需更改类定义即可轻松扩展,但我在这里持开放态度,因此是最初的问题。
【解决方案2】:

如果您的业务对象像这样干净,我建议您查看 ORM 映射器,例如 Hibernate 或 ActiveObjects。

如果您更愿意构建自己的数据访问层,我建议使这些类尽可能轻量级。例如在Order 中,我将有一个代表外键的CustomerID 整数字段,而不是在Order 业务类中返回一个Customer 对象的getCustomer()

诸如getCustomer() 之类的获取方法可能会更好地放置在包含您的数据访问功能的不同类中,例如CustomerDAO 等。

从效率的角度来看,您采用哪种方法并不重要,但拥有松散耦合的对象始终是一种好习惯。

【讨论】:

  • 我想我已经建立了自己的数据访问层,它工作得很好。我只是想知道约定和最佳实践。
  • 这种轻量级类的使用是否是松散耦合的示例?
  • 不,这不符合“松耦合”的条件。它更像是“混淆耦合”,因为关系仍然存在,只是通过 int 键隐藏。不过,松散耦合的最佳实践根本不适用于数据模型。
  • '诸如 getCustomer() 之类的获取方法可能会更好地放置在包含您的数据访问功能的其他类中,例如 CustomerDAO 等。 Order 中获取订单行的方法也可以这样说吗?还是应该将这样的方法放在 DAO 中的 Order 或 OrderLines 中?
  • 我认为 getOrderLines() 方法也应该在数据访问类中,我只是想让我的对象对其他业务对象知之甚少,并且与它们建模的表非常相似。我认为应该由数据访问类来管理这些模型和持久层之间的关系。事实上,我用“松散耦合”来描述这一点是不正确的。
【解决方案3】:

您应该查看一些对象关系映射 (ORM) 映射工具,例如 HibernateTopLink,或者可能是更简单的查询映射工具,例如 iBatis

如果你沿着 ORM 路线走,我认为你最终会得到更像你的第二个建议的东西。

【讨论】:

    【解决方案4】:

    执行此操作的常用方法是使用对象关系映射库 (ORM)。常见的有:

    所有这些都是开源库,并实现了 JPA(Java Persistence Architecture)标准。

    【讨论】:

      【解决方案5】:

      我还鼓励您查看像 Hibernate 这样的对象关系映射工具,或者像 iBatis 这样更简单的 SQL 映射工具。 (我对 iBatis 的体验非常好。)

      关于对 Order 及其 OrderLine 之间的主从关系建模的问题,在 Java 对象级别,它们当然是相同概念层次结构的一部分,因此我会选择将它们建模为包含 List 的 Order 对象.这样我就可以在我的代码周围传递完整的订单,而不必担心丢失部分订单。

      如果您使用像 iBatis 这样的 SQL 映射器,您需要在数据库中设置一个 Order 表和一个 OrderLine 表,并为 iBatis 提供一个 XML 映射,告诉它如何组装您的复合 Java Order/OrderLine 对象层次结构通过将两个 SQL 表连接在一起。 ORM 反向操作,根据您的 Java 数据模型生成 SQL 表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 2010-12-21
        • 2010-11-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多