好吧,这可能是一个微不足道的问题,但我很难想象和理解它们的区别,以及何时使用它们。我还不太清楚像单向映射和双向映射这样的概念如何影响一对多/多对多关系。我现在使用的是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
}

在这种情况下,会有什么样的映射呢?希望您能回答这个特定的示例,但我还想了解一下什么时候使用一对多和多对多,什么时候使用连接表和连接列,什么时候使用单向和双向。


当前回答

看一下这篇文章:映射对象关系

映射时需要考虑两类对象关系。第一类是基于多样性的,包括三种类型:

*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. 

第二类是基于 方向性,它包含两个 类型,单向关系 以及双向关系。

*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. 

其他回答

首先,阅读所有的小字。注意,NHibernate(因此,我认为Hibernate也是如此)关系映射与DB和对象图映射有一种有趣的对应关系。例如,一对一关系通常被实现为多对一关系。

其次,在我们告诉你应该如何写你的O/R图之前,我们也必须看到你的DB。特别是,一项技能可以被多人拥有吗?如果是这样,你有一个多对多关系;否则就是多对一。

第三,我不喜欢直接实现多对多关系,而是在您的域模型中对“连接表”建模。,将其视为一个实体,如下所示:

class PersonSkill 
{
    Person person;
    Skill skill;    
}

那你知道你有什么了吗?您有两个一对多的关系。(在本例中,Person可能有一个PersonSkills集合,但不会有一个Skills集合。)然而,有些人更喜欢使用多对多关系(人与技能之间);这是有争议的。

第四,如果你确实有双向关系(例如,不仅Person有一个技能集合,而且Skill也有一个Person集合),NHibernate不会在你的BL中强制执行双向关系;它只理解关系的双向性以实现持久性。

第五,在NHibernate(我假设是Hibernate)中,多对一比一对多(集合映射)更容易正确使用。

好运!

我会这样解释:

有个关系

@OneToOne
Person person;

@OneToOne
Nose nose;

一对多-多对一的关系

@OneToMany
Shepherd shepherd;

@ManyToOne
List<Sheep> sheeps;

多对多-多对多关系

@ManyToMany
List<Traveler> travelers;

@ManyToMany
List<Destination> destinations;

一对多:一个人有很多技能,一个技能在人之间不会重复使用。

单向:一个人可以直接通过他的技能集引用技能 双向:每个“子”技能都有一个指向 Person(在代码中没有显示)

多对多:一个人拥有多个技能,一个技能在多个人之间重复使用。

单向:一个人可以直接通过他的技能集引用技能 双向:一项技能有一组与之相关的人。

在一对多关系中,一个对象是“父对象”,一个是“子对象”。父元素控制子元素的存在。在多对多中,任何一种类型的存在都依赖于它们之外的东西(在更大的应用程序上下文中)。

您的主题(领域)应该规定关系是一对多还是多对多——然而,我发现使关系单向还是双向是一种工程决策,需要权衡内存、处理、性能等。

令人困惑的是,多对多双向关系不需要是对称的!也就是说,一群人可以指向一项技能,但该技能不需要只与这些人相关。通常情况下是这样的,但这种对称性并不是必需的。以爱为例——它是双向的(“我爱”,“爱我”),但通常是不对称的(“我爱她,但她不爱我”)!

所有这些都得到Hibernate和JPA的良好支持。请记住,Hibernate或任何其他ORM在管理双向多对多关系时并不关心保持对称性……这完全取决于应用程序。

看起来每个人都在回答一对多和多对多的问题:

一对多、多对一和多对多的区别是:

一对多vs多对一是个角度的问题。单向和双向不会影响映射,但会在访问数据的方式上有所不同。

在多对一中,多方将保持对一方的参考。一个很好的例子是“一个州有城市”。在这种情况下,国家是一方,城市是多方。在表cities中会有一个列state_id。

在单向中,Person类将拥有List<Skill>技能但是 技能不会有人缘的人。在双向方面,两者都有 属性被添加,它允许您访问给定的Person 技能(即技能。人)。

在一对多中,一方将是我们的参照点。例如,“A User has Addresses”。在这种情况下,我们可能有三个列address_1_id, address_2_id和address_3_id,或者有一个多列唯一约束user_id的查找表 address_id。

在单向中,用户将有地址地址。双向 将在Address类中有一个额外的List<User>用户。

在多对多中,每一方的成员都可以引用另一方的任意数量的成员。为了实现这一点,使用了一个查找表。医生和病人之间的关系就是一个例子。一个医生可以有很多病人,反之亦然。

这可能需要如下所示的多对多关系



public class Person{

    private Long personId;
    @manytomany

    private Set skills;
    //Getters and setters
}

public class Skill{
    private Long skillId;
    private String skillName;
    @manyToMany(MappedBy="skills,targetClass="Person")
    private Set persons; // (people would not be a good convenion)
    //Getters and setters
}

你可能需要定义一个joinTable + JoinColumn,但它也可能没有…