18

这一定很幼稚,但我对何时使用@Entityand有疑问@Embeddable

说我有一个UserNotification类。

 @Entity
 public class User{
     //other properties
     @onetomany
     private List<Notification> notifications;
 }

 @Entity
 public class Notification{
     //properties
 }

我知道将有用于 classUserNotification的表,以及用于映射的第三个表。如果我这样做呢?

 @Entity
 public class User {
     //other properties
     @ElementCollection
     private List<Notification> notifications;
 }

 @Embeddable
 public class Notification{
     //properties
 }

我知道这不会为Notification. 但我仍然可以存储我的通知对象。我浏览了文档,但有几个疑问:

  1. 是否基于我是否希望将 B 类视为单独的表?
  2. 创建表和可嵌入对象是否存在性能差异?
  3. 除了直接查询表之外,我不能对可以对表执行的可嵌入对象做什么?

笔记

对于阅读此问题的任何人,此问题也可能对您有所帮助。

4

2 回答 2

10
  1. 是否基于我是否希望将 B 类视为单独的表?

是的,当您使用时,您将该实体@Embedded嵌入到类中,这使得它可以在同一个类表中添加嵌入实体的列。@Embeddable@Entity@Entity

  1. 创建表和可嵌入对象是否存在性能差异?

当您使用@Embedded, 创建表时,需要一个查询,也需要插入和选择一行。但是,如果您不使用它,则需要多个查询,因此,@Embedded我们可以说,使用会产生更高的性能。

  1. 除了直接查询表之外,我不能对可以对表执行的可嵌入对象做什么?

可能会移除相应的嵌入实体,但可能会违反完整性约束。

于 2012-10-04T07:31:59.523 回答
0

在 JPA 中,有几种方法可以创建复合键字段。让我们看看使用@Embeddable annotation.
让我们从 Entity 类开始。

@Entity
@Table
public class TraceRecord {
    @Id
    private TraceRecordPk id;

    @Version
    @Transient
    private int version;

    @Column(columnDefinition = "char")
    private String durationOfCall;

    @Column(columnDefinition = "char")
    private String digitsDialed;

    @Column(columnDefinition = "char")
    private String prefixCalled;

    @Column(columnDefinition = "char")
    private String areaCodeCalled;

    @Column(columnDefinition = "char")
    private String numberCalled;
}

这是一个非常简单的 Entity 类,带有一个 @Id 和 @Version 字段以及一些 @Column 定义。无需过多介绍,您将看到@Version 字段也被注释为@Transient。我这样做只是因为我的表也没有用于跟踪版本的列,但是我的数据库是日志记录的,所以我不太关心版本控制。您还会注意到@Column 字段在 columnDefinition 属性上设置了“char”值。这是因为我的表中的字段被定义为 char 而不是 varchar。如果它们是 varchar,我不需要这样做,因为默认情况下 String 映射到 varchar 字段。

这个@Id领域是我现在感兴趣的。它不是标准的 Java 类型,而是我自己定义的类。这是那堂课。

@Embeddable
public class TraceRecordPk implements Serializable {

    private static final long serialVersionUID = 1L;

    @Temporal(TemporalType.DATE)
    @Column
    private Date dateOfCall;

    @Column(columnDefinition="char")
    private String timeOfCall;

    @Column(columnDefinition="char")
    private String callingParty;

    /**
     * Constructor that takes values for all 3 members.
     *
     * @param dateOfCall Date the call was made
     * @param timeOfCall Time the call was made
     * @param callingParty Extension from which the call originated
     */
    public TraceRecordPk(Date dateOfCall, String timeOfCall, String callingParty) {
        this.dateOfCall = dateOfCall;
        this.timeOfCall = timeOfCall;
        this.callingParty = callingParty;
    }
}

为了使这个类能够成为实体类上的@Id 字段,它需要像我之前提到的那样使用@Embeddable 进行注释。我为复合键选择的 3 个字段只是普通的 @Column 定义。我没有为每个字段创建 getter/setter,而是简单地实现了一个构造函数,它为所有 3 个字段获取值,使任何实例都不可变。当使用 @Embeddable 注释一个类时,该类将需要实现 Serializable。所以我添加了一个默认的serialVersionUID 来适应。

现在您已经创建了一个用 注释的类@Embeddable,您现在可以将它用作 Entity 类中 @Id 字段的类型。简单的东西嗯。

于 2012-10-04T06:41:58.770 回答