Ian*_*las 129 orm many-to-many hibernate one-to-many
好的,这可能是一个微不足道的问题,但我无法想象和理解差异以及何时使用每个差异.关于单向和双向映射等概念如何影响一对多/多对多关系,我也有点不清楚.我现在正在使用Hibernate,所以任何与ORM相关的解释都会有所帮助.
举个例子,假设我有以下设置:
public class Person{
private Long personId;
private Set<Skill> skills;
//Getters and setters
}
public class Skill{
private Long skillId;
private String skillName;
//Getters and setters
}
Run Code Online (Sandbox Code Playgroud)
那么在这种情况下我会有什么样的映射?这个具体示例的答案肯定是值得赞赏的,但我也非常希望概述何时使用一对多和多对多以及何时使用连接表与连接列以及单向与双向.
Ale*_*hel 214
貌似每个人都回答One-to-manyVS Many-to-many:
之间的区别One-to-many,Many-to-one并Many-to-Many为:
One-to-manyvs Many-to-one是一个透视问题.Unidirectionalvs Bidirectional不会影响映射,但会对您访问数据的方式产生影响.
Many-to-one该many侧将保持基准one侧.一个很好的例子是"一个人有很多技能".在这种情况下Stage是一方而且City是多方面.state_id表格中会有一列cities.在单向
Person类中将有List<Skill> skills但Skill不会有Person person.在双向中,两个属性都被添加,它允许您访问Person给定的技能(即skill.person).
One-to-Many很多方面将是我们的参考点.例如,"用户有地址".在我们的系统中,许多用户可能共享一个地址(例如,许多人可能共享相同的块号).在这种情况下,表中的address_1_id列address_2_id将由多个address_3_id行共享.在这种情况下,我们说user_id并且address_id有User关系.在单向一个
Address address将有List<User> users.双向 将Address在Many-to-Many课堂上增加一个.
One-to-many每一方的成员可以参考另一方的任意数量的成员.为此,使用查找表.这方面的例子是医生和患者之间的关系.医生可以有很多患者,反之亦然.HDa*_*ave 154
一对多:一个人有很多技能,一个技能不会在人与人之间重复使用
多对多:一个人有很多技能,一个技能在人之间重复使用
在一对多关系中,一个对象是"父",一个是"子".父母控制孩子的存在.在多对多中,任何一种类型的存在都依赖于它们之外的某些东西(在较大的应用程序上下文中).
你的主题(领域)应该决定关系是一对多还是多对多 - 然而,我发现使关系单向或双向是一种工程决策,可以消除内存,处理,性能等
令人困惑的是,多对多双向关系不需要是对称的!也就是说,一群人可以指出一项技能,但技能不需要仅涉及那些人.通常它会,但这种对称性不是必需的.以爱为例 - 它是双向的("我爱","爱我"),但通常是不对称的("我爱她,但她不爱我")!
所有这些都得到Hibernate和JPA的很好支持.请记住,在管理双向多对多关系时,Hibernate或任何其他ORM都没有提供关于保持对称性的声音......这完全取决于应用程序.
jhe*_*dus 35
1)圆圈是实体/ POJOs /豆
2)deg是度数的缩写,如图(边数)
PK =主键,FK =外键
注意程度和名称之间的矛盾.许多对应于degree = 1而One对应于degree> 1.

Vla*_*cea 25
一对多表关系如下所示:
在关系数据库系统中,一对多表关系基于Foreign Key子表中的一列引用Primary Key父表中的一条记录来关联两个表。
上表post_id中,post_comment表中的列Foreign Key与post表idPrimary Key列有关系:
ALTER TABLE
post_comment
ADD CONSTRAINT
fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
Run Code Online (Sandbox Code Playgroud)
在 JPA 中,映射一对多表关系的最佳方式是使用@ManyToOne注解。
在我们的例子中,PostComment子实体post_id使用@ManyToOne注释映射外键列:
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
@Id
@GeneratedValue
private Long id;
private String review;
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
}
Run Code Online (Sandbox Code Playgroud)
@OneToMany注释仅仅因为您可以选择使用@OneToMany注释,并不意味着它应该是所有一对多数据库关系的默认选项。
JPA 集合的问题是我们只能在它们的元素数量相当低时使用它们。
映射@OneToMany关联的最佳方法是依靠@ManyToOne侧来传播所有实体状态更改:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
//Constructors, getters and setters removed for brevity
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
}
Run Code Online (Sandbox Code Playgroud)
父Post实体具有两个实用方法(例如addComment和removeComment),用于同步双向关联的双方。
每当您使用双向关联时,您都应该提供这些方法,否则,您可能会面临非常微妙的状态传播问题。
@OneToMany应避免单向关联,因为它比使用@ManyToOne或双向@OneToMany关联效率低。
一对一的表关系如下所示:
在关系数据库系统中,一对一的表关系基于Primary Key子表中的列链接两个表,该列也是父表行的Foreign Key引用Primary Key。
因此,我们可以说子表Primary Key与父表共享。
在上面的表格图id中,post_details表格中的列也Foreign Key与post表格id Primary Key列有关系:
ALTER TABLE
post_details
ADD CONSTRAINT
fk_post_details_id
FOREIGN KEY (id) REFERENCES post
Run Code Online (Sandbox Code Playgroud)
@OneToOne带有@MapsId注释的 JPA映射@OneToOne关系的最佳方法是使用@MapsId. 这样,您甚至不需要双向关联,因为您始终可以PostDetails使用Post实体标识符获取实体。
映射如下所示:
@Entity(name = "PostDetails")
@Table(name = "post_details")
public class PostDetails {
@Id
private Long id;
@Column(name = "created_on")
private Date createdOn;
@Column(name = "created_by")
private String createdBy;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "id")
private Post post;
public PostDetails() {}
public PostDetails(String createdBy) {
createdOn = new Date();
this.createdBy = createdBy;
}
//Getters and setters omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
这样,该id属性既用作主键又用作外键。您会注意到该@Id列不再使用@GeneratedValue注释,因为标识符填充了post关联的标识符。
多对多表关系如下所示:
在关系数据库系统中,多对多表关系通过子表链接两个父表,子表包含Foreign Key引用Primary Key两个父表的列的两列。
在上面的表图post_id中,post_tag表中的列也Foreign Key与post表idPrimary Key列有关系:
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_post_id
FOREIGN KEY (post_id) REFERENCES post
Run Code Online (Sandbox Code Playgroud)
而且,tag_id在列post_tag表中有一个Foreign Key与关系tag表IDPrimary Key列:
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_tag_id
FOREIGN KEY (tag_id) REFERENCES tag
Run Code Online (Sandbox Code Playgroud)
@ManyToMany映射这是您如何many-to-many使用 JPA 和 Hibernate映射表关系:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "post_tag",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private Set<Tag> tags = new HashSet<>();
//Getters and setters ommitted for brevity
public void addTag(Tag tag) {
tags.add(tag);
tag.getPosts().add(this);
}
public void removeTag(Tag tag) {
tags.remove(tag);
tag.getPosts().remove(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Post)) return false;
return id != null && id.equals(((Post) o).getId());
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}
@Entity(name = "Tag")
@Table(name = "tag")
public class Tag {
@Id
@GeneratedValue
private Long id;
@NaturalId
private String name;
@ManyToMany(mappedBy = "tags")
private Set<Post> posts = new HashSet<>();
//Getters and setters ommitted for brevity
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Tag tag = (Tag) o;
return Objects.equals(name, tag.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
Run Code Online (Sandbox Code Playgroud)
tags关联Post只定义了PERSIST和MERGE级联类型。在REMOVE实体状态转换不会使一个任何意义@ManyToManyJPA的关联,因为它可能引发连锁的缺失,最终将擦拭协会的两侧。Post实体使用的相等实体标识符,因为它没有任何独特的业务重点。只要确保它在所有实体状态转换中保持一致,就可以使用实体标识符来表示相等性。Tag实体具有唯一的业务键,该键标有 Hibernate 特定的@NaturalId注释。在这种情况下,唯一的业务键是平等检查的最佳候选者。mappedBy属性标志着,在这种双向关系中,实体拥有该关联。这是必需的,因为只有一方可以拥有关系,并且更改仅从这一特定方传播到数据库。postsTagPostSet是优选的,如使用List具有@ManyToMany效率较低。Dur*_*aco 14
我会这样解释:
OneToOne - OneToOne (一个人有一个鼻子 - 一个鼻子有一个人)
@OneToOne
Person person;
@OneToOne
Nose nose;
Run Code Online (Sandbox Code Playgroud)
OneToMany - ManyToOne (一个牧羊人有很多羊 - 一只羊有一个牧羊人)
@OneToMany
Shepherd shepherd;
@ManyToOne
List<Sheep> sheeps;
Run Code Online (Sandbox Code Playgroud)
ManyToMany - ManyToMany
(许多旅行者有很多目的地 -
许多目的地有很多旅行者)
@ManyToMany
List<Traveler> travelers;
@ManyToMany
List<Destination> destinations;
Run Code Online (Sandbox Code Playgroud)
看看这篇文章:映射对象关系
映射时需要关注两类对象关系.第一类基于多重性,它包括三种类型:
*One-to-one relationships. This is a relationship where the maximums of each of its multiplicities is one, an example of which is holds relationship between Employee and Position in Figure 11. An employee holds one and only one position and a position may be held by one employee (some positions go unfilled).
*One-to-many relationships. Also known as a many-to-one relationship, this occurs when the maximum of one multiplicity is one and the other is greater than one. An example is the works in relationship between Employee and Division. An employee works in one division and any given division has one or more employees working in it.
*Many-to-many relationships. This is a relationship where the maximum of both multiplicities is greater than one, an example of which is the assigned relationship between Employee and Task. An employee is assigned one or more tasks and each task is assigned to zero or more employees.
Run Code Online (Sandbox Code Playgroud)
第二类基于方向性,它包含两种类型,单向关系和双向关系.
*Uni-directional relationships. A uni-directional relationship when an object knows about the object(s) it is related to but the other object(s) do not know of the original object. An example of which is the holds relationship between Employee and Position in Figure 11, indicated by the line with an open arrowhead on it. Employee objects know about the position that they hold, but Position objects do not know which employee holds it (there was no requirement to do so). As you will soon see, uni-directional relationships are easier to implement than bi-directional relationships.
*Bi-directional relationships. A bi-directional relationship exists when the objects on both end of the relationship know of each other, an example of which is the works in relationship between Employee and Division. Employee objects know what division they work in and Division objects know what employees work in them.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
92209 次 |
| 最近记录: |