Java @用于映射集合的可嵌入vs@entity
这一定很幼稚,但我怀疑什么时候应该使用Java @用于映射集合的可嵌入vs@entity,java,spring,hibernate,jpa,orm,Java,Spring,Hibernate,Jpa,Orm,这一定很幼稚,但我怀疑什么时候应该使用@Entity和@embeddedable 假设我有一个用户和通知类 @Entity public class User{ //other properties @onetomany private List<Notification> notifications; } @Entity public class Notification{ //properties } 我知道这不会为通知创建
@Entity
和@embeddedable
假设我有一个用户
和通知
类
@Entity
public class User{
//other properties
@onetomany
private List<Notification> notifications;
}
@Entity
public class Notification{
//properties
}
我知道这不会为通知创建表。但我仍然可以存储通知对象。我仔细检查了一下,但有几个疑问:
是否基于我是否希望将B类视为一个单独的表
创建表和可嵌入对象时是否存在性能差异
除了直接查询表之外,我可以对表执行的可嵌入对象执行哪些操作
注释
对于阅读此问题的任何人来说,这也可能对您有所帮助。在JPA中,有几种方法可以创建复合键字段。让我们看看使用@embeddedable注释的方法
让我们从实体类开始
@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定义。我没有为每个字段创建getter/setter,而是简单地实现了一个构造函数,它接受所有3个字段的值,使任何实例都是不可变的。用@Embeddeble注释类时,该类需要实现可序列化。因此,我添加了一个默认的serialVersionUID来容纳
现在您已经创建了一个类,并使用@embeddeble
对其进行了注释,现在可以将其用作实体类中@Id字段的类型。简单的东西啊
是否基于我是否希望将B类视为一个单独的表
是的,当您使用@Embedded
时,您将@Embedded
实体嵌入到@entity
类中,这使得它可以在@entity
类的同一个表中为嵌入的实体添加列
@Entity
public class User{
//other properties
@onetomany
private List<Notification> notifications;
}
@Entity
public class Notification{
//properties
}
创建表和可嵌入对象时是否存在性能差异
使用@Embedded
创建表时,需要一个查询,也需要插入和选择行。但是,如果不使用它,则需要多个查询,因此,可以说,使用@Embedded
会产生更高的性能
除了直接查询表之外,我可以对表执行的可嵌入对象执行哪些操作
删除相应的嵌入实体可能是错误的,但可能会违反完整性约束。谢谢,但我已经读过了。它没有回答我的问题。我的问题与复合键无关。我想我可以使用Embeddeble with ElementCollection。我不需要使用@嵌入式RT?第三点:考虑人包含地址(嵌入式),如果有两个单独的表,则可以直接删除关联的地址,但是如果人的表有F.K.地址,则可能会导致完整性约束违反。“@可嵌入”使得类有嵌入的资格。“嵌入式”实际上嵌入了可嵌入实体。这对Embedded和Embedded给出了很好的解释,非常感谢:)这确实有帮助:)