わかりましたので、これはおそらく些細な質問ですが、違いとそれぞれをいつ使用するかを視覚化して理解するのに苦労しています。また、単方向および双方向マッピングのような概念が1対多/多対多の関係にどのように影響するかについても少し不明瞭です。現在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
}
この場合、どのようなマッピングがありますか?この特定の例に対する回答は間違いなく高く評価されますが、1対多および多対多のどちらを使用するか、および結合テーブルと結合列、および単方向と双方向を使用するタイミングの概要も非常に気に入っています。
1対多:1人の人間に多くのスキルがあり、スキルは個人間で再利用されません
多対多:1人の人に多くのスキルがあり、スキルは人の間で再利用されます
1対多の関係では、1つのオブジェクトが「親」で、もう1つのオブジェクトが「子」です。親は子の存在を制御します。多対多では、どちらかのタイプが存在するかどうかは、両方の外側の何か(より大きなアプリケーションコンテキスト内)に依存します。
主題(ドメイン)は、リレーションシップが1対多または多対多であるかどうかを決定する必要があります-ただし、リレーションシップを単方向または双方向にすることは、メモリ、処理、パフォーマンスをトレードオフするエンジニアリング上の決定であることがわかりますなど.
紛らわしいのは、多対多の双方向の関係が対称である必要がないことです!つまり、多くの人々がスキルを指すことができますが、スキルはそれらの人々だけに関連する必要はありません。通常はそうなりますが、そのような対称性は必須ではありません。たとえば、愛を考えてみましょう。双方向(「I-Love」、「Loves-Me」)ですが、多くの場合非対称(「私は彼女を愛していますが、彼女は私を愛していません」)です。
これらはすべて、HibernateおよびJPAによって十分にサポートされています。 Hibernateまたは他のORMは、双方向の多対多のリレーションシップを管理する際に対称性を維持することについては気に留めないことを覚えておいてください...それはすべてアプリケーション次第です。
誰もがOne-to-many
対Many-to-many
に答えているようです:
One-to-many
、Many-to-one
、およびMany-to-Many
の違いは次のとおりです。
One-to-many
vs Many-to-one
は視点の問題です。 Unidirectional
vs Bidirectional
はマッピングに影響しませんが、データへのアクセス方法に違いが生じます。
One-to-many
では、many
側はone
側の参照を保持します。良い例は「人は多くのスキルを持っている」です。この場合、Person
は片側で、Skill
は多側です。テーブルskills
には列person_id
があります。unidirectional
Person
クラスにはList<Skill> skills
がありますが、Skill
にはPerson person
がありません。 bidirectionalで両方のプロパティが追加され、スキル(つまりskill.person
)が与えられたPerson
にアクセスできます。
Many-to-one
では、多くの側面が参照ポイントになります。たとえば、「ユーザーにはアドレスがあります」。このシステムでは、多くのユーザーがアドレスを共有する場合があります(たとえば、多くの人が同じブロック番号を共有する場合があります)。その場合、users
テーブルのaddress_id
列は、複数のusers
行で共有されます。この場合、users
とaddresses
はMany-to-one
関係にあると言います。unidirectionalでは、
User
はAddress address
になります。 Bidirectionalには、Address
クラスにList<User> users
が追加されます。
Many-to-Many
では、各パーティのメンバーは、相手の任意の数のメンバーへの参照を保持できます。これを実現するために、 ルックアップテーブル が使用されます。この例は、医師と患者の関係です。医師は多くの患者を抱えることがあり、その逆もあります。1)円は、エンティティ/ POJO/Beanです
2)degは、グラフのように次数を表す略語です(エッジの数)
PK =プライマリキー、FK =外部キー
学位とサイドの名前の矛盾に注意してください。多くは次数= 1に対応し、一方は次数> 1に対応します。
この記事をご覧ください: マッピングオブジェクトの関係
マッピングの際に考慮する必要があるオブジェクトの関係には2つのカテゴリがあります。最初のカテゴリは多重度に基づいており、3つのタイプが含まれています。
*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.
2番目のカテゴリは方向性に基づいており、単方向の関係と双方向の関係の2つのタイプが含まれています。
*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.
これはおそらく次のような多対多の関係シップを必要とします
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を定義する必要があるかもしれませんが、それがなくても動作する可能性があります...
まず第一に、すべての細かい活字を読んでください。 NHibernate(したがって、Hibernateも同様です)リレーショナルマッピングは、DBおよびオブジェクトグラフマッピングとおもしろく対応していることに注意してください。たとえば、1対1の関係は、多くの場合、多対1の関係として実装されます。
第二に、O/Rマップをどのように記述するかを伝える前に、DBも確認する必要があります。特に、単一のスキルを複数の人が所有できますか?もしそうなら、あなたは多対多の関係を持っています。それ以外の場合は、多対1です。
第三に、多対多のリレーションシップを直接実装するのではなく、ドメインモデルで「結合テーブル」をモデル化することを好みます。つまり、次のようにエンティティとして扱います。
class PersonSkill
{
Person person;
Skill skill;
}
次に、あなたが持っているものを見ますか? 2つの1対多の関係があります。 (この場合、PersonにはPersonSkillのコレクションがありますが、Skillのコレクションはありません。)ただし、一部のユーザーは多対多の関係(PersonとSkillの間)を使用することを好みます。これは議論の余地があります。
第4に、双方向の関係がある場合(たとえば、Personにスキルのコレクションがあるだけでなく、Skillにもコレクションがある)、NHibernateはnot BLの双方向性を強制します;永続化のために関係の双方向性のみを理解します。
5番目に、多対1(コレクションマッピング)よりもNHibernate(およびHibernateを想定)で多対1を正しく使用する方がはるかに簡単です。
幸運を!