JPA 最佳实践? [关闭]
Posted
技术标签:
【中文标题】JPA 最佳实践? [关闭]【英文标题】:JPA best practices? [closed] 【发布时间】: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
有没有更好或更常见的方法来做到这一点?
【问题讨论】:
【参考方案1】:请参阅Lee Chuk Munn 的 JPA 最佳实践 的幻灯片。你可以在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 对象(域对象)
-
要使用的 java REST 客户端
REST 服务器接受这个对象作为参数,并且
将此对象保存到数据库中。
我认为这是一个常见的用例。
有这么多注解,使用这个对象的客户端需要所有的 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;
【讨论】:
你不需要所有的依赖,因为注解类不必在运行时可用:***.com/questions/3567413/…。【参考方案6】:将实体用作域对象并没有错。您必须注意使用已分离的实体等,但可以管理。
我不会通过强制将每个实体映射到另一个 bean(或 POJO)来人为地为自己创建工作。有时需要将许多实体(或来自实体的值)包装到一个 bean 中,但只有在有充分理由时才这样做。
【讨论】:
【参考方案7】:我看不出有这样的两个并行对象层次结构的理由。我会拥有实体并放弃您所谓的 POJO。不需要映射。这是对 CPU 周期的浪费,而我看不到任何好处。
【讨论】:
【参考方案8】:也许混淆是由于实体是只是一个带有映射信息的 POJO(在代码中作为注释或在单独的配置文件中)。只要您愿意,就可以作为 POJO 工作(您可以创建和修改对象;只要您不使用 Session 保存它们,它们就不会被写入 DB)。
有时您可能需要将数据保存在不是实体的 bean 中(主要是因为该 bean 由另一个框架管理并且您不想混合 *1),那么您只需复制(通过特定的构造函数,通过调用大量的 set...(), 不管) 从你的 bean 到你的 Entity/POJO 的数据。
*1 我在这里想到的是 JSF。
【讨论】:
以上是关于JPA 最佳实践? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章