【问题标题】:JPA best practices? [closed]JPA 最佳实践? [关闭]
【发布时间】:2011-10-28 12:33:36
【问题描述】:

我正在开发一个使用 JPA/EclipseLink 作为持久层的小型多层应用程序。在我目前的设计中,我有两组对象,POJO 和实体对象,我将 POJO 用于一般编程任务,而实体类用于 DB 读/写和表映射​​。

现在是否需要 POJO=>Entity 映射(有问题),然后是第二个 Entity==>DB 表映射(JPA 注释)?我发现使用 Entity 类作为我的主要 java 对象并在必要时保留它们更容易,毕竟 Entity 类本质上是带有几个 JPA 注释的 POJO。

同样在确实需要将事物分开的情况下,执行 POJO=>Entity 映射的最佳位置是什么,目前我在 CRUD 方法中执行此操作,例如

public void addCustomerPOJO(Customer customerPOJO){
   //Cteat EntityManager and start a Transaction

   //Create Entity class and populate it with values 
   //from the passed-in regular (non entity) Customer class

  //Persiste and close
}

有没有更好或更常见的方法来做到这一点?

【问题讨论】:

    标签: java jpa entity pojo


    【解决方案1】:

    请参阅Lee Chuk MunnJPA 最佳实践 的幻灯片。你可以在JPA Best Practices - Indo Java Podcast找到它。

    【讨论】:

    • 两个链接都失效了。
    • @OrtomalaLokni 嘿,你好吗? :) 我使用 Wayback Machine 的捕获更新了链接。
    【解决方案2】:

    我的 0.20 美元

    除非您能记住代码中的关系是如何标记的,并且 它们何时由休眠填充以及何时/何地访问它们 在代码中我建议你使用 DTO 方法。

    但是,如果您正在学习 hibernate 或打算在小型项目中使用它,您可能很容易从控制器层返回实体(或它们的集合)。

    但我敢肯定,你做的越多,你就越需要 移至 DTO 甚至 JsonView。如果你不是那个 构建 UI,您会更快地意识到这一点。

    说到 DTO,我最喜欢的是 ModelMapper。您可以在控制器层进行转换(简单和复杂的任何您喜欢的)。这样你就可以知道你在 DTO 中返回了什么。

    【讨论】:

      【解决方案3】:

      您可能需要使用另一组类来防止涟漪效应。具有多个依赖项的 Web 服务通常会出现这种情况。数据映射通常会增加程序的复杂性,应在没有正当理由的情况下避免。

      【讨论】:

        【解决方案4】:

        我目前正在使用 JPA 服务于后端的三累 Java EE 应用程序。我使用单个 java 类来表示数据库中的每个表(实体类)并且我使用相同的类来执行所有操作,包括业务层和数据库层。这也很有意义。 因为在所有三层中,您都可以独立地创建同一个实体类的实例。

        PS - @Hay:即使当我开始学习 JPA 时,我也在用两组不同的相同类进行操作 :) 我猜,这种做法是因为 EJB 2.1 出现的,因为 EJB 2.1 中没有任何注释。所以基本上需要两组不同的类,其中一组必须完全专用于 DAO 操作的实体类。 随着 JPA 的发展,注释被带入画面,这让我们的生活变得轻松......旧习惯确实很难死;)

        【讨论】:

          【解决方案5】:

          注解确实有其缺点,尤其是在多层 Java EE 应用程序中。

          在下面的例子中,你有一个你想要的简单 POJO 对象(域对象)

          1. 要使用的 java REST 客户端
          2. REST 服务器接受这个对象作为参数,并且
          3. 将此对象保存到数据库中。

          我认为这是一个常见的用例。

          有这么多注解,使用这个对象的客户端需要所有的 jar 依赖。我想可以将注解移到 XML 文件中,但是这样就失去了注解的优势。

          还有其他创造性的解决方案吗?

          @Data
          @Entity
          @XmlRootElement(name="sport")
          @Table(name = "db_sport")
          @NamedQueries({
             @NamedQuery(name = "Sport.findAll", query = "SELECT d FROM Sport d")})
          public class Sport implements Serializable {
             @Id
             @GeneratedValue(strategy = GenerationType.AUTO)
             @Basic(optional = false)
             @Column(name = "sportId")
             int sportId;
          }
          

          【讨论】:

          【解决方案6】:

          将实体用作域对象并没有错。您必须注意使用已分离的实体等,但可以管理。

          我不会通过强制将每个实体映射到另一个 bean(或 POJO)来人为地为自己创建工作。有时需要将许多实体(或来自实体的值)包装到一个 bean 中,但只有在有充分理由时才这样做。

          【讨论】:

            【解决方案7】:

            我看不出有这样的两个并行对象层次结构的理由。我会拥有实体并放弃您所谓的 POJO。不需要映射。这是对 CPU 周期的浪费,而我看不到任何好处。

            【讨论】:

              【解决方案8】:

              也许混淆是由于实体只是一个带有映射信息的 POJO(在代码中作为注释或在单独的配置文件中)。只要您愿意,就可以作为 POJO 工作(您可以创建和修改对象;只要您不使用 Session 保存它们,它们就不会被写入 DB)。

              有时您可能需要将数据保存在不是实体的 bean 中(主要是因为该 bean 由另一个框架管理并且您不想混合 *1),那么您只需复制(通过特定的构造函数,通过调用大量的 set...(), 不管) 从你的 bean 到你的 Entity/POJO 的数据。

              *1 我在这里想到的是 JSF。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-10-02
                • 2010-10-06
                • 2010-09-10
                • 2011-10-11
                • 1970-01-01
                • 2014-04-26
                • 1970-01-01
                相关资源
                最近更新 更多