问题
Ok so this is probably a trivial question but I\'m having trouble visualizing and understanding the differences and when to use each. I\'m also a little unclear as to how concepts like uni-directional and bi-directional mappings affect the one-to-many/many-to-many relationships. I\'m using Hibernate right now so any explanation that\'s ORM related will be helpful.
As an example let\'s say I have the following set-up:
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
}
So in this case what kind of mapping would I have? Answers to this specific example are definitely appreciated but I would also really like an overview of when to use either one-to-many and many-to-many and when to use a join table versus a join column and unidirectional versus bidirectional.
回答1:
One-to-Many: One Person Has Many Skills, a Skill is not reused between Person(s)
- Unidirectional: A Person can directly reference Skills via its Set
- Bidirectional: Each "child" Skill has a single pointer back up to the Person (which is not shown in your code)
Many-to-Many: One Person Has Many Skills, a Skill is reused between Person(s)
- Unidirectional: A Person can directly reference Skills via its Set
- Bidirectional: A Skill has a Set of Person(s) which relate to it.
In a One-To-Many relationship, one object is the "parent" and one is the "child". The parent controls the existence of the child. In a Many-To-Many, the existence of either type is dependent on something outside the both of them (in the larger application context).
Your subject matter (domain) should dictate whether or not the relationship is One-To-Many or Many-To-Many -- however, I find that making the relationship unidirectional or bidirectional is an engineering decision that trades off memory, processing, performance, etc.
What can be confusing is that a Many-To-Many Bidirectional relationship does not need to be symmetric! That is, a bunch of People could point to a skill, but the skill need not relate back to just those people. Typically it would, but such symmetry is not a requirement. Take love, for example -- it is bi-directional ("I-Love", "Loves-Me"), but often asymmetric ("I love her, but she doesn't love me")!
All of these are well supported by Hibernate and JPA. Just remember that Hibernate or any other ORM doesn't give a hoot about maintaining symmetry when managing bi-directional many-to-many relationships...thats all up to the application.
回答2:
Looks like everyone is answering One-to-many
vs Many-to-many
:
The difference between One-to-many
, Many-to-one
and Many-to-Many
is:
One-to-many
vs Many-to-one
is a matter of perspective. Unidirectional
vs Bidirectional
will not affect the mapping but will make difference on how you can access your data.
- In
Many-to-one
themany
side will keep reference of theone
side. A good example is "A State has Cities". In this caseStage
is the one side andCity
is the many side. There will be a columnstate_id
in the tablecities
.
In unidirectional
Person
class will haveList<Skill> skills
butSkill
will not havePerson person
. In bidirectional both properties are added and it allows you to access aPerson
given a skill( i.e.skill.person
).
- In
One-to-Many
the one side will be our point of reference. For example, "A User has an Addresses". In this case we might have three columnsaddress_1_id
,address_2_id
andaddress_3_id
or a look up table with unique constraint onuser_id
andaddress_id
.
In unidirectional a
User
will haveAddress address
. Bidirectional will have an additionalList<User> users
in theAddress
class.
- In
Many-to-Many
members of each party can hold reference to arbitrary number of members of the other party. To achieve this a look up table is used. Example for this is the relationship between doctors and patients. A doctor can have many patients and vice versa.
回答3:
1) The circles are Entities/POJOs/Beans
2) deg is an abbreviation for degree as in graphs (number of edges)
PK=Primary key, FK=Foreign key
Note the contradiction between the degree and the name of the side. Many corresponds to degree=1 while One corresponds to degree >1.

回答4:
Take a look at this article: Mapping Object Relationships
There are two categories of object relationships that you need to be concerned with when mapping. The first category is based on multiplicity and it includes three types:
*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.
The second category is based on directionality and it contains two types, uni-directional relationships and bi-directional relationships.
*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.
回答5:
this would probably call for a many-to-many relation ship as follows
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
}
you may need to define a joinTable + JoinColumn but it will possible work also without...
回答6:
First of all, read all the fine print. Note that NHibernate (thus, I assume, Hibernate as well) relational mapping has a funny correspondance with DB and object graph mapping. For example, one-to-one relationships are often implemented as a many-to-one relationship.
Second, before we can tell you how you should write your O/R map, we have to see your DB as well. In particular, can a single Skill be possesses by multiple people? If so, you have a many-to-many relationship; otherwise, it's many-to-one.
Third, I prefer not to implement many-to-many relationships directly, but instead model the "join table" in your domain model--i.e., treat it as an entity, like this:
class PersonSkill
{
Person person;
Skill skill;
}
Then do you see what you have? You have two one-to-many relationships. (In this case, Person may have a collection of PersonSkills, but would not have a collection of Skills.) However, some will prefer to use many-to-many relationship (between Person and Skill); this is controversial.
Fourth, if you do have bidirectional relationships (e.g., not only does Person have a collection of Skills, but also, Skill has a collection of Persons), NHibernate does not enforce bidirectionality in your BL for you; it only understands bidirectionality of the relationships for persistence purposes.
Fifth, many-to-one is much easier to use correctly in NHibernate (and I assume Hibernate) than one-to-many (collection mapping).
Good luck!
回答7:
I would explain that way:
OneToOne - OneToOne relationship
@OneToOne
Person person;
@OneToOne
Nose nose;
OneToMany - ManyToOne relationship
@OneToMany
List<Shepherd> shepherd;
@ManyToOne
Sheep sheep;
ManyToMany - ManyToMany relationship
@ManyToMany
List<Traveler> traveler;
@ManyToMany
List<Destination> destination;
来源:https://stackoverflow.com/questions/3113885/difference-between-one-to-many-many-to-one-and-many-to-many