有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

映射集合的java@Embeddeble vs@entity

这一定很幼稚,但我怀疑何时使用@Entity@Embeddable

假设我有一个UserNotification

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

 @Entity
 public class Notification{
     //properties
 }

我知道会有用于类UserNotification的表,以及用于映射的第三个表。 如果我这样做怎么办

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

 @Embeddable
 public class Notification{
     //properties
 }

我知道这不会为Notification创建表。但我仍然可以存储通知对象。我经历了documentation,但有两个疑问:

  1. 是否基于我是否希望将B类视为一个单独的表
  2. 创建表和可嵌入对象时是否存在性能差异
  3. 除了直接查询表之外,我可以对表执行的可嵌入对象执行哪些操作

注释

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


共 (2) 个答案

  1. # 1 楼答案

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

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

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

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

    1. 除了直接查询表之外,我可以对表执行的可嵌入对象执行哪些操作

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

  2. # 2 楼答案

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

    @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;
    }
    

    这是一个非常简单的实体类,具有@Id和@Version字段以及一些@Column定义。不必太详细,您将看到@Version字段也被注释为@Transient。我这样做的原因很简单,因为我的表也没有用于跟踪版本的列,但我的数据库是日志记录的,所以我不太关心版本控制。您还会注意到@Column字段在columnDefinition属性上设置了一个值“char”。这是因为我的表中的字段定义为char而不是varchar。如果它们是varchar,我就不需要这样做,因为默认情况下字符串映射到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字段,需要像我前面提到的那样用@embeddeble注释它。我为复合键选择的3个字段只是普通的@Column定义。我为每个实例创建一个字段设置器,而不是为每个实例创建一个不可变的字段设置器。用@Embeddeble注释类时,该类需要实现可序列化。因此,我添加了一个默认的serialVersionUID来容纳

    现在已经创建了一个类,并用@Embeddable进行了注释,现在可以将其用作实体类中@Id字段的类型。简单的东西啊