一对多、多对一和多对多之间的区别?

发布于 2024-09-07 03:01:08 字数 464 浏览 7 评论 0原文

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

那么在这种情况下我会有什么样的映射?非常感谢这个特定示例的答案,但我也非常希望概述何时使用一对多和多对多,何时使用连接表与连接列以及单向与双向。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

安静 2024-09-14 03:01:08

看起来每个人都在回答一对多多对多

一对多之间的区别>多对一多对多是:

一对多 vs 多对一< /code> 是一个视角问题单向双向 不会影响映射,但会对您访问数据的方式产生影响。

  • 多对一中,端将保留端的引用。一个很好的例子是“一个州有城市”。在本例中,State 是一侧,City 是多侧。 cities 表中会有一列 state_id

单向中,Person 类将具有 List技能但是
Skill不会有Person person。在双向中,两者
添加了属性,它允许您访问给定的 Person
技能(即skill.person)。


  • 一对多中,一侧将是我们的参考点。例如,“用户有地址”。在这种情况下,我们可能有三列 address_1_idaddress_2_idaddress_3_id 或一个 使用 user_id 上的多列唯一约束
    address_id 上。

单向中,用户将拥有地址双向
将有一个额外的 ListAddress 类中的用户

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

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 the many side will keep reference of the one side. A good example is "A State has Cities". In this case State is the one side and City is the many side. There will be a column state_id in the table cities.

In unidirectional, Person class will have List<Skill> skills but
Skill will not have Person person. In bidirectional, both
properties are added and it allows you to access a Person 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 Addresses". In this case we might have three columns address_1_id, address_2_id and address_3_id or a look up table with multi column unique constraint on user_id
    on address_id.

In unidirectional, a User will have Address address. Bidirectional
will have an additional List<User> users in the Address 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.
木槿暧夏七纪年 2024-09-14 03:01:08

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

  • 单向:一个人可以通过其集合直接引用技能
  • 双向:每个“子”技能都有一个指向
    人员(代码中未显示)

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

  • 单向:一个人可以通过其集合双向直接引用技能
  • :技能具有与其相关的一组人员。

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

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

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

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

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.

各自安好 2024-09-14 03:01:08

1) 圆圈是实体/POJO/Bean

2) deg 是图形中度的缩写(边数)

PK=主键,FK=外键

请注意度与边名称之间的矛盾。许多对应于度=1,而一对应于度>1。

一对多多对一插图

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.

Illustration of one-to-many many-to-one

缱倦旧时光 2024-09-14 03:01:08

一对多

一对多表关系如下所示:

One-to-many

在关系数据库系统中,一对多表关系基于子表中引用父表中一条记录的主键外键列来关联两个表。

在上表中,post_comment 表中的 post_id 列与 post 表具有 Foreign Key 关系id Primary Key 列:

    ALTER TABLE
        post_comment
    ADD CONSTRAINT
        fk_post_comment_post_id
    FOREIGN KEY (post_id) REFERENCES post

@ManyToOne 注解

在 JPA 中,映射一对多表关系的最佳方法是使用 @ManyToOne 注解。

在我们的示例中,PostComment 子实体使用 @ManyToOne 注释映射 post_id 外键列:

    @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;
        
    }

使用 JPA @OneToMany< /code> 注释

仅仅因为您可以选择使用 @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);
        }
    }

Post 实体功能两个实用方法(例如addCommentremoveComment)用于同步双向关联的双方。

每当您使用双向关联时,您都应该提供这些方法,否则您将面临 非常微妙的状态传播问题

应避免使用单向 @OneToMany 关联,因为它的效率低于使用 @ManyToOne 或双向 @OneToMany 关联。

一对一

一对一表关系如下所示:

One-to-one

在关系数据库系统中,一对一的表关系基于子表中的主键列链接两个表,该列也是引用主键外键 > 父表行。

因此,我们可以说子表与父表共享主键。

在上表中,post_details 表中的 id 列与 post 也具有 Foreign Key 关系表 id Primary Key 列:

    ALTER TABLE
        post_details
    ADD CONSTRAINT
        fk_post_details_id
    FOREIGN KEY (id) REFERENCES post

使用带有 @MapsId 注释的 JPA @OneToOne 映射

< code>@OneToOne关系是使用@MapsId。这样,您甚至不需要双向关联,因为您始终可以使用 Post 实体标识符来获取 PostDetails 实体。

映射如下所示:

@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
}

这样,id 属性既充当主键又充当外键。您会注意到,@Id 列不再使用 @GenerateValue 注释,因为标识符是用 post 关联的标识符填充的。

多对多

多对多表关系如下所示:

Many-to-many

在关系数据库系统中,多对多表关系通过子表链接两个父表,子表包含两个引用两个父表的主键列的外键列。

在上表中,post_tag 表中的 post_id 列与 post 也具有 Foreign Key 关系表 id Primary Key 列:

    ALTER TABLE
        post_tag
    ADD CONSTRAINT
        fk_post_tag_post_id
    FOREIGN KEY (post_id) REFERENCES post

并且,post_tag 表中的 tag_id 列与tag 表 id Primary Key 列:

    ALTER TABLE
        post_tag
    ADD CONSTRAINT
        fk_post_tag_tag_id
    FOREIGN KEY (tag_id) REFERENCES tag

使用 JPA @ManyToMany 映射

这是映射多对多< /code> 与 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);
        }
    }
  1. Post 实体中的 tags 关联仅定义 PERSISTMERGE > 级联类型。 REMOVE 实体状态转换对于 @ManyToMany JPA 关联没有任何意义,因为它可能会触发链删除,最终擦除关联的双方。
  2. 如果您使用双向关联,则添加/删除实用程序方法是必需的,以便您可以确保关联的双方保持同步。
  3. Post 实体使用实体标识符来实现平等,因为它缺少任何唯一的业务密钥。您可以使用实体标识符来实现相等,只要确保它在所有实体状态转换中保持一致即可。
  4. Tag 实体有一个唯一的业务键,它用 Hibernate 特定的 @NaturalId 注解进行标记。在这种情况下,唯一的业务密钥是平等检查的最佳候选
  5. Tag 实体中 posts 关联的 mappedBy 属性标记,在此双向关系中,Post 实体拥有该协会。这是必需的,因为只有一侧可以拥有关系,并且更改仅从该特定一侧传播到数据库。
  6. Set 是首选,因为使用 List@ManyToMany 效率较低。

One-to-many

The one-to-many table relationship looks like this:

One-to-many

In a relational database system, a one-to-many table relationship associates two tables based on a Foreign Key column in the child table referencing the Primary Key of one record in the parent table.

In the table diagram above, the post_id column in the post_comment table has a Foreign Key relationship with the post table id Primary Key column:

    ALTER TABLE
        post_comment
    ADD CONSTRAINT
        fk_post_comment_post_id
    FOREIGN KEY (post_id) REFERENCES post

@ManyToOne annotation

In JPA, the best way to map the one-to-many table relationship is to use the @ManyToOne annotation.

In our case, the PostComment child entity maps the post_id Foreign Key column using the @ManyToOne annotation:

    @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;
        
    }

Using the JPA @OneToMany annotation

Just because you have the option of using the @OneToMany annotation, it doesn't mean it should be the default option for all the one-to-many database relationships.

The problem with JPA collections is that we can only use them when their element count is rather low.

The best way to map a @OneToMany association is to rely on the @ManyToOne side to propagate all entity state changes:

    @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);
        }
    }

The parent Post entity features two utility methods (e.g. addComment and removeComment) which are used to synchronize both sides of the bidirectional association.

You should provide these methods whenever you are working with a bidirectional association as, otherwise, you risk very subtle state propagation issues.

The unidirectional @OneToMany association is to be avoided as it's less efficient than using @ManyToOne or the bidirectional @OneToMany association.

One-to-one

The one-to-one table relationship looks as follows:

One-to-one

In a relational database system, a one-to-one table relationship links two tables based on a Primary Key column in the child which is also a Foreign Key referencing the Primary Key of the parent table row.

Therefore, we can say that the child table shares the Primary Key with the parent table.

In the table diagram above, the id column in the post_details table has also a Foreign Key relationship with the post table id Primary Key column:

    ALTER TABLE
        post_details
    ADD CONSTRAINT
        fk_post_details_id
    FOREIGN KEY (id) REFERENCES post

Using the JPA @OneToOne with @MapsId annotations

The best way to map a @OneToOne relationship is to use @MapsId. This way, you don't even need a bidirectional association since you can always fetch the PostDetails entity by using the Post entity identifier.

The mapping looks like this:

@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
}

This way, the id property serves as both Primary Key and Foreign Key. You'll notice that the @Id column no longer uses a @GeneratedValue annotation since the identifier is populated with the identifier of the post association.

Many-to-many

The many-to-many table relationship looks as follows:

Many-to-many

In a relational database system, a many-to-many table relationship links two parent tables via a child table which contains two Foreign Key columns referencing the Primary Key columns of the two parent tables.

In the table diagram above, the post_id column in the post_tag table has also a Foreign Key relationship with the post table id Primary Key column:

    ALTER TABLE
        post_tag
    ADD CONSTRAINT
        fk_post_tag_post_id
    FOREIGN KEY (post_id) REFERENCES post

And, the tag_id column in the post_tag table has a Foreign Key relationship with the tag table id Primary Key column:

    ALTER TABLE
        post_tag
    ADD CONSTRAINT
        fk_post_tag_tag_id
    FOREIGN KEY (tag_id) REFERENCES tag

Using the JPA @ManyToMany mapping

This is how you can map the many-to-many table relationship with JPA and 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);
        }
    }
  1. The tags association in the Post entity only defines the PERSIST and MERGE cascade types. The REMOVE entity state transition doesn't make any sense for a @ManyToMany JPA association since it could trigger a chain deletion that would ultimately wipe both sides of the association.
  2. The add/remove utility methods are mandatory if you use bidirectional associations so that you can make sure that both sides of the association are in sync.
  3. The Post entity uses the entity identifier for equality since it lacks any unique business key. You can use the entity identifier for equality as long as you make sure that it stays consistent across all entity state transitions.
  4. The Tag entity has a unique business key which is marked with the Hibernate-specific @NaturalId annotation. When that's the case, the unique business key is the best candidate for equality checks.
  5. The mappedBy attribute of the posts association in the Tag entity marks that, in this bidirectional relationship, the Post entity owns the association. This is needed since only one side can own a relationship, and changes are only propagated to the database from this particular side.
  6. The Set is to be preferred, as using a List with @ManyToMany is less efficient.
叫嚣ゝ 2024-09-14 03:01:08

我会这样解释:

OneToOne - OneToOne
(一个人有一个鼻子 -
一鼻子有一个人)

@OneToOne
Person person;

@OneToOne
Nose nose;

OneToMany - ManyToOne
(一个牧羊人有很多只羊 -
一只羊有一个牧羊人)

@OneToMany
Shepherd shepherd;

@ManyToOne
List<Sheep> sheeps;

ManyToMany - ManyToMany
(许多旅行者有很多目的地 -
许多目的地都有许多旅客)

@ManyToMany
List<Traveler> travelers;

@ManyToMany
List<Destination> destinations;

I would explain that way:

OneToOne - OneToOne
(One Person has one Nose -
One Nose has one Peson)

@OneToOne
Person person;

@OneToOne
Nose nose;

OneToMany - ManyToOne
(One Shepherd has many sheeps -
One sheep has one Shepherd)

@OneToMany
Shepherd shepherd;

@ManyToOne
List<Sheep> sheeps;

ManyToMany - ManyToMany
(Many travelers have many destinations -
Many destinations have many travelers)

@ManyToMany
List<Traveler> travelers;

@ManyToMany
List<Destination> destinations;
幻想少年梦 2024-09-14 03:01:08

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

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

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

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. 
空袭的梦i 2024-09-14 03:01:08

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



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 但它也可以在没有...的情况下工作

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

挽心 2024-09-14 03:01:08

首先,阅读所有细则。请注意,NHibernate(因此,我假设也是 Hibernate)关系映射与数据库和对象图映射有一个有趣的对应关系。例如,一对一关系通常被实现为多对一关系。

其次,在我们告诉您应该如何编写 O/R 映射之前,我们还必须查看您的数据库。尤其是,一个技能可以被多人拥有吗?如果是这样,那么你们之间就是多对多关系;否则,就是多对一。

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

class PersonSkill 
{
    Person person;
    Skill skill;    
}

那么你看到你拥有什么了吗?您有两个一对多关系。 (在这种情况下,Person 可能有 PersonSkills 的集合,但不会有 Skills 的集合。)但是,有些人会更喜欢使用多对多关系(Person 和 Skill 之间);这是有争议的。

第四,如果您确实有双向关系(例如,Person 不仅有 Skills 的集合,而且 Skill 也有 Persons 的集合),NHibernate 不会在您的 BL 中为您强制执行双向性;它仅出于持久性目的而理解关系的双向性。

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

祝你好运!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文