好吧,这可能是一个微不足道的问题,但我很难想象和理解这些差异以及何时使用它们。我还不太清楚单向和双向Map等概念如何影响一对多/多对多关系。我现在正在使用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
}
那么在这种情况下我会有什么样的Map呢?对于这个具体例子的答案,我非常感激,但我也很想概述一下什么时候使用一对多和多对多,什么时候使用连接表和连接列,什么时候使用单向和双向。
8条答案
按热度按时间46qrfjad1#
看起来每个人都在回答
One-to-many
与。Many-to-many
:One-to-many
,Many-to-one
和Many-to-Many
的区别是:One-to-many
vsMany-to-one
是一个Angular 问题。Unidirectional
与Bidirectional
不会影响Map,但会影响您如何访问数据。Many-to-one
中,many
侧将保留one
侧的引用。一个很好的例子是“一个国家有城市”。在这种情况下,State
是一侧,City
是多侧。表cities
中将有一列state_id
。在 * 单向 * 中,
Person
类将有List<Skill> skills
,但Skill
将没有Person person
。在 bidirectional 中,这两个属性都被添加了,它允许你在给定技能的情况下访问Person
(即skill.person
)。One-to-Many
中,一侧将是我们的参考点。例如,“一个用户有一个用户”。在这种情况下,我们可能有三个列address_1_id
,address_2_id
和address_3_id
或look up table,其中multi column unique constraint在user_id
在address_id
上。在 * 单向 * 中,
User
将具有Address address
。Bidirectional 将在Address
类中增加List<User> users
。Many-to-Many
中,每一方的成员可以引用另一方的任意数量的成员。为了实现这一点,使用了look up table。这方面的例子是医生和病人之间的关系。一个医生可以有很多病人,反之亦然。ukdjmx9f2#
一对多:一个人有很多技能,技能不能在人与人之间重复使用
*单向:一个人可以直接引用技能通过其集
*双向:每个“子”技能都有一个指向Person的指针(在代码中没有显示)
多对多:一个人有很多技能,技能在人与人之间重复使用
*单向:一个人可以直接引用技能通过其集
*双向:一个技能有一组与之相关的人。
在一对多关系中,一个对象是“父对象”,另一个对象是“子对象”。父母控制孩子的存在。在多对多中,任何一种类型的存在都依赖于它们之外的东西(在更大的应用程序上下文中)。
你的主题(领域)应该决定关系是一对多还是多对多--然而,我发现使关系单向或双向是一个权衡内存、处理、性能等的工程决策。
令人困惑的是,多对多双向关系不需要是对称的!也就是说,一群人可以指向一个技能,但这个技能不需要仅仅与这些人相关。通常是这样的,但这种对称性不是必要条件。以爱为例,它是双向的(“我爱”,“爱我”),但往往是不对称的(“我爱她,但她不爱我”)!
所有这些都得到了Hibernate和JPA的支持。请记住,Hibernate或任何其他ORM都不会在管理双向多对多关系时给予关于保持对称性的提示.
gorkyyrv3#
1)圆圈是实体/POJO/Bean
2)deg是度的缩写,如图中的度(边数)
PK=主键,FK=外键
请注意度数和边的名称之间的矛盾。许多对应于度=1,而一个对应于度>1。
6ie5vjzr4#
一对多
一对多表关系如下所示:
在关系数据库系统中,一对多表关系基于子表中的
Foreign Key
列引用父表中一条记录的Primary Key
来关联两个表。在上面的表格关系图中,
post_comment
表格中的post_id
列与post
表格idPrimary Key
列具有Foreign Key
关系:@ManyToOne annotation
在JPA中,Map一对多表关系的最佳方式是使用
@ManyToOne
注解。在我们的例子中,
PostComment
子实体使用@ManyToOne
注解Mappost_id
外键列:使用JPA
@OneToMany
注解仅仅因为您可以选择使用
@OneToMany
注解,并不意味着它应该是所有 * 一对多 * 数据库关系的默认选项。JPA集合的问题是,我们只能在它们的元素数量相当少的时候使用它们。
Map
@OneToMany
关联的最佳方式是依赖@ManyToOne
端来传播所有实体状态更改:父
Post
实体具有两个实用程序方法(例如,addComment
和removeComment
),其用于同步双向关联的两侧。无论何时使用双向关联,您都应该提供这些方法,否则您将面临very subtle state propagation issues的风险。
应该避免单向
@OneToMany
关联,因为它的效率低于使用@ManyToOne
或双向@OneToMany
关联。一对一
一对一表关系如下所示:
在关系数据库系统中,一对一表关系基于子表中的
Primary Key
列链接两个表,该列也是引用父表行的Primary Key
的Foreign Key
。因此,我们可以说子表与父表共享
Primary Key
。在上面的表格关系图中,
post_details
表格中的id
列也与post
表格中的id
Primary Key
列具有Foreign Key
关系:使用带
@MapsId
注解的JPA@OneToOne
Map
@OneToOne
关系的最佳方法是使用@MapsId
。这样,您甚至不需要双向关联,因为您总是可以通过使用Post
实体标识符来获取PostDetails
实体。Map如下所示:
这样,
id
属性既充当主键又充当外键。您会注意到,@Id
列不再使用@GeneratedValue
注解,因为标识符填充了post
关联的标识符。多对多
多对多表关系如下所示:
在关系数据库系统中,多对多表关系通过子表链接两个父表,子表包含引用两个父表的
Primary Key
列的两个Foreign Key
列。在上面的表格关系图中,
post_tag
表中的post_id
列也与post
表idPrimary Key
列具有Foreign Key
关系:而且,
post_tag
表中的tag_id
列与tag
表idPrimary Key
列具有Foreign Key
关系:使用JPA
@ManyToMany
Map下面是如何将
many-to-many
表关系Map到JPA和Hibernate:Post
实体中的tags
关联仅定义PERSIST
和MERGE
级联类型。REMOVE
实体状态转换对于@ManyToMany
JPA关联没有任何意义,因为它可能触发链删除,最终删除关联的两端。1.如果您使用双向关联,则添加/删除实用程序方法是必需的,以便您可以确保关联的两端同步。
Post
实体使用实体标识符进行相等,因为它缺少任何唯一的业务键。只要确保实体标识符在所有实体状态转换中保持一致,就可以使用实体标识符来实现相等性。Tag
实体有一个唯一的业务密钥,该密钥标记有特定于Hibernate的@NaturalId
注解。在这种情况下,唯一业务密钥是the best candidate for equality checks。Tag
实体中的posts
关联的mappedBy
属性标记,在此双向关系中,Post
实体拥有该关联。这是必要的,因为只有一方可以拥有关系,并且更改只能从这一特定方传播到数据库。Set
是首选,因为使用List
和@ManyToMany
效率较低。v6ylcynt5#
我会这样解释:
一对一-一对一(一个人有一个鼻子-一个鼻子有一个比索)
OneToMany - ManyToOne(一个牧羊人有许多牧羊人-一只羊有一个牧羊人)
ManyToMany - ManyToMany(许多旅行者有许多目的地-
许多目的地有许多旅行者)
brjng4g36#
看看这篇文章:Map对象关系
Map时需要关注两类对象关系。第一类基于多样性,包括三种类型:
第二类是基于方向性的,它包括两种类型,单向关系和双向关系。
cidc1ykv7#
这可能需要如下的多对多关系
你可能需要定义一个joinTable + JoinColumn,但它也可以工作,没有.
xtupzzrd8#
首先,阅读所有的小字。请注意,NHibernate(因此,我假设Hibernate也是如此)关系Map与DB和对象图Map有一个有趣的对应关系。例如,一对一关系通常被实现为多对一关系。
第二,在我们告诉你应该如何编写O/RMap之前,我们还必须看看你的数据库。尤其是一个技能,能被多个人拥有吗?如果是这样的话,你有一个多对多的关系;否则就是多对一
第三,我不喜欢直接实现多对多关系,而是在域模型中对“连接表”进行建模--即,将其视为一个实体,如下所示:
那你看看你有什么您有两个一对多关系。(在这种情况下,Person可能有一个PersonSkills的集合,但不会有Skills的集合。)然而,有些人更喜欢使用多对多关系(Person和Skill之间);这是有争议的。
第四,如果你有双向关系(例如,不仅Person有Skills的集合,Skill也有Person的集合),NHibernate不会在BL中为你强制双向性;它仅理解用于持久性目的的关系的双向性。
第五,在NHibernate(我假设是Hibernate)中,多对一比一对多(集合Map)更容易正确使用。
祝你好运!