10.関連関係マッピングの基礎(1)


10.関連関係マッピングの基礎(1)


エンティティの多くは他のエンティティに関連しています.たとえば、受注エンティティは商品エンティティに関連付けられ、商品エンティティはカテゴリ、在庫などの他のエンティティに関連付けられます.ただし、オブジェクトは参照(アドレス)を使用して関係を確立し、テーブルは外部キーを使用して関係を確立します.この2つは全く異なる特徴を持っている.オブジェクトリレーションシップマッピング(ORM)で最も困難な部分は、オブジェクトリレーションシップとテーブルリレーションシップのマッピングです.
この章の目的は、オブジェクトの参照とテーブルの外部キーをマッピングすることです.
開始前に,関連関係マッピングを理解する鍵となるキーワードを整理した.行いながら理解しよう
  • 方向:[一方向、双方向]があります.たとえば、メンバーがチームと関係がある場合、メンバー->チームまたはチーム->メンバーのうち一方のみが参照され、一方向関係と呼ばれます.メンバー->チーム、チーム->メンバーの両方が相互参照され、双方向関係と呼ばれます.方向はオブジェクト関係にのみ存在し、テーブル関係は常に双方向です.
  • 多重性:[多対一(N:1),一対多(1:1),多対多(N:M)]多重性.たとえば、会員とチームが関係している場合、複数のメンバーは1つのチームに属するため、会員とチームは複数対1の関係になります.逆に、1つのチームは複数のメンバーを持つことができるので、チームとメンバーは1対多の関係です.
  • 関連関係の所有者:オブジェクトを双方向関連関係として作成する場合は、関連関係の所有者を決定する必要があります.
  • 1.一方向関連


    関連関係では,まず多対一(N:1)の一方向関係を理解する.これから、会員とチームの関係を通じて、多対一の一方的な関係を理解します.
  • 会員とチームがいます.
  • 会員は1つのチームにしか属しません.
  • 会員とチームは多対一の関係です.

  • 上の画像を分析してください.
    オブジェクト関連
  • メンバーオブジェクトはメンバーです.チームオブジェクトにteamフィールド(メンバー変数)を使用して関連付けます.
  • 会員オブジェクトとチームオブジェクトは一方向関係です.メンバーはメンバーです.チームはteamfieldで理解できますが、逆にチームはメンバーを理解できません.たとえば、メンバー->チームのクエリーはメンバーです.getTeam()は使用できますが、反対方向のteam->memberのフィールドにはアクセスしません.
  • 表の関連付け
  • 会員表はTEAM ID外部キーを使用して表と関連付けられている.
  • 会員表とチーム表は双方向関係です.会員表のTEAM ID外部キーで会員とチームを検索できます.逆も同様です.たとえば、MEMBERテーブルのTEAM ID外部キーの1つで、MEMBER JOIN TEAMとTEAM JOIN MEMBERのどちらでも構いません.
  • 外部キーで双方向に接続する方法について説明します.以下は会員とチームに署名したSQLです.
    SELECT *
    FROM MEMBER M
    JOIN TEAM T ON M.TEAM_ID = T.ID
    以下は反対者グループと会員に署名したSQLです.
    SELECT *
    FROM TEAM T
    JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID
    オブジェクトの関連付けとテーブルの関連付けの最大の違い
    参照による関連関係は常に一方向です.オブジェクト間で双方向の関連付けを作成する場合は、参照を保持するために別の端にフィールドを追加する必要があります.最終的には関連関係を構築する必要があります.このように互いに参照し合うことを双方向関連関係と呼ぶ.しかし、正確には、これは双方向関係ではなく、2つの異なる一方向関係である.逆に、1つのテーブルは外来の鍵で2つの港の部屋にサインすることができます.
    次は、一方向関連です.
    class A {
        B b;
    }
    class B {}
    次に、双方向関連関係を示します.
    class A {
        B b;
    }
    class B {
        A a;
    }
    オブジェクトの関連付けとテーブルの関連付けの整理
  • オブジェクトは、参照(アドレス)によって関連付けられます.
  • テーブルは、外部キーで関連付けられます.
  • この二つは似ているように見えるが、まったく異なる特徴を持っている.関連データを問い合わせると、オブジェクトが参照されます(a.getB().getC()を使用しますが、テーブルはJOINを使用します.
  • を使用して参照されるオブジェクトの関連付けは一方向です.
    - A -> B(a.b)
  • 外部キーを使用するテーブルの関連付けは一方向です.
    -A JOIN Bでよろしければ反対のB JOIN Aでも構いません
  • オブジェクトを双方向に参照するには、2つの一方向関連関係を確立する必要があります.
    - A -> B(a.b)
    - B -> A(b.a)
  • これまで,オブジェクト関連関係とテーブル関連関係の違いを理解してきた.次に、純粋なオブジェクト関連の例と純粋なテーブル関連の例を表示し、両方をマッピングします.

    1.純オブジェクト関連


    純粋に使用するオブジェクトの関連関係を理解してみましょう.次の例は、JPAを使用していない純粋な会員およびチームクラスのコードです.
    public class Member {
        
        private String id;
        private String username;
        
        private Team team;  // 팀의 참조를 보관
        
        public void setTeam(Team team) {
            this.team = team;
        }
        
        // Getter, Setter ...
    }
    
    public class Team {
    
        private String id;
        private String name;
        
        // Getter, Setter...
    }
    上記の例を実行して、メンバー1とメンバー2をチーム1に追加します.
    public static void main(String[] args) {
    
        // 생성자(id, 이름)
        Member member1 = new Member("member1", "회원1");
        Member member2 = new Member("member2", "회원2");
        Team team1 = new Team("team1", "팀1");
        
        member1.setTeam(team1);
        member2.setTeam(team1);
        
        Team findTeam = member1.getTeam();
    }
    次の図は、クラス関係とインスタンス関係を示しています.

    上図に示すように,会員1と会員2はグループ1に属する.次に、以下のコードを使用して会員1が属するチーム1を問い合わせることができます.
    Team findTeam = member1.getTeam();
    このように、オブジェクトは参照を使用して関連関係を参照できます.これをオブジェクトグラフィックブラウズと呼びます.

    2.表の関連


    今回は、データベース・テーブルのメンバーとチームの関係を見てみましょう.次の例は、メンバー・テーブルとチーム・テーブルのDDLです.また,会員表のTEAM IDには外部キー制約条件が設定されている.
    CREATE TABLE MEMBER (
        MEMBER_ID VARCHAR(255) NOT NULL,
        TEAM_ID VARCHAR(255),
        USERNAME VARCHAR(255),
        PRIMARY KEY (MEMBER_ID)
    )
    
    CREATE TABLE TEAM (
        TEAM_ID VARCHAR(255) NOT NULL,
        NAME VARCHAR(255),
        PRIMARY KEY (TEAM_ID)
    )
    
    ALTER TABLE MEMBER ADD CONSTRAINT FK_MEMBER_TEAM 
        FOREIGN KEY (TEAM_ID)
        REFERENCES TEAM    
    以下のSQLを実行して、会員1と会員2をチーム1に加入します.
    INSERT INTO TEAM(TEAM_ID, NAME) VALUES('team1', '팀1');
    INSERT INTO MEMBER(MEMBER_ID, TEAM_ID, USERNAME) VALUES('member1', 'team1', '회원1');
    INSERT INTO MEMBER(MEMBER_ID, TEAM_ID, USERNAME) VALUES('member2', 'team1', '회원2');
    以下のSQLを実行して、会員1のチームを検索します.
    SELECT T.*
    FROM MEMBER M
        JOIN TEAM T ON M.TEAM_ID = T.ID
    WHERE M.MEMBER_ID = 'member1'
    このように、データベースは外部キーを使用して関連関係を探索することができます.これを結合と呼びます.

    3.オブジェクト関係のマッピング


    これまで,オブジェクトのみを用いた関連関係とテーブルのみを用いた関連関係をそれぞれ理解してきた.JPAを使用して両者をマッピングします.
    @Entity
    public class Member {
    
        @Id
        @Column(name = "MEMBER_ID")
        private String id;
        
        private String usrename;
        
        // 연관관계 매핑
        @ManyToOne
        @JoinColumn(name="TEAM_ID")
        private Team team;
        
        // 연관관계 설정
        public void setTeam(Team team) {
            this.team = team;
        }
        
        // Getter, Setter
    }
    @Entity
    public class Team {
    
        @Id
        @Column(name = "TEAM_ID")
        private String id;
        
        private String name;
        
        // Getter, Setter
    }
    上記のサンプルコードは、メンバーエンティティとチームエンティティをマッピングします.コードを解析する前に、上図の「関連関係マッピング」セクションを参照してください.
  • オブジェクト関連:メンバー・オブジェクトのメンバー.teamフィールド
  • の使用
  • 表関連関係:会員表のMEMBER.TEAM ID外部キー列
  • を使用
    Member.チームとメンバー.マッピングTEAM IDは関連関係マッピングである.関連関係マッピングコードを分析します.
    @ManyToOne
    @JoinColumn(name="TEAM_ID")
    private Team team;
    これは、メンバー・エンティティの「≪関連関係マッピング|Relationship Mappings|emdw≫」セクションで、関連関係をマッピングするための新しい構文があります.
  • @ManyToOne:名前の通り、多対一(N:1)関係というマッピング情報です.会員とチームは多対一の関係です.関連関係をマッピングする場合は、多重性を表す構文を使用する必要があります.
  • @JoinColumn(name="TEAM ID"):外部キーをマッピングするための結合カラム.nameプロパティは、マッピングする外部キーの名前を指定します.メンバーとチームテーブルはTEAM ID外部キーを使用して関連付けられているので、この値を指定すればよい.次の説明は省略できます.
  • 関連関係マッピングツールについて詳しく説明します.

    4. @JoinColumn


    @JoinColumnは外部キーのマッピングに使用します.次の表では、主なプロパティをまとめます.
    ツールバーの
    機能
    デフォルト
    name
    マップする外部キー名
    フィールド名++参照テーブルのプライマリ・キー列名
    referencedColumnName
    外部キーが参照するターゲット・テーブルのカラム名.
    参照テーブルのプライマリ・キー列名
    foreignKey(DDL)
    外部キー制約を直接指定できます.このプロパティは、テーブルの作成時にのみ使用されます.
    uniquenullableinsertableupdatablecolumnDefinitiontable
    @Columnのプロパティと同じです.
    スキップ@JoinColumn
    下図のように@JoinColumnを省略すると、外部キーを検索するときにデフォルトのポリシーが使用されます.
    @ManyToOne
    private Team team;
  • 基本ポリシー:フィールド名++参照テーブルのカラム名
  • フィールド名(team)+(アンダースコア)+参照テーブルのカラム名(TEAM ID)=team TEAM ID外部キーを使用します.
  • 5. @ManyToOne


    @ManyToOne宣言は、複数対1の関係で使用されます.次の表では、主なプロパティをまとめます.
    ツールバーの
    機能
    デフォルト
    optional
    falseに設定した場合、関連するエンティティは常に存在する必要があります.
    true
    fetch
    グローバルパッチ戦略を策定します.
    -@ManyToOne=FetchType.EAGER-@OneToMany=FetchType.LAZY
    cascade
    永続的な移行機能を使用します.
    関連エンティティのタイプ情報を設定します.この機能はあまり使いません.コレクションを使用しても、ネットワークを通じてタイプ情報を知ることができます.
    次のコードはtargetEntityプロパティの使用例です.
    @OneToMany
    private List<Member> members;  // 제네릭을 타입 정보를 알 수 있다.
    
    @OneToMany(targetEntity=Member.class)
    private List members;    // 제네릭이 없으면 타입 정보를 알 수 없다.
    関連関係マッピング操作が完了しました.マッピングの関連付けが使用されます.
    多対一のような一対一の関係もある.一方的な関係を考慮しない場合、どちらを使用するかは別の関係に依存します.相手が一対多の関係であれば、多対一、相手が一対一の関係であれば、一対一を使うことができます.
    リファレンス
  • Java ORM標準JPAプログラミング