Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

양방향 연관관계와 연관관계 주인. 본문

인프런/[인프런] 자바ORM 표준 JPA 프로그래밍

양방향 연관관계와 연관관계 주인.

Seung__ 2021. 8. 10. 18:20

1. 단방향, 양방향 매핑


  • 단방향 연관관계를 양방향으로 바꿔도 table은 변화가 없다.
  • MEMBER은 TEAM_ID(FK)와 TEAM의 PK를 Join
  • 반대로 TEAM은 TEAM_ID(PK)와 MEMBER의 FK와 Join하면됨
  • 즉!!!!!!!!! TABLE은 FK하나로 양방향으로 매핑이 된다!!!!
  • 방향의 개념보다는 FK하나로 양쪽이 연관관계가 생김.
  • 근데 객체는 그렇지 않다.
  • 따라서 Team객체에 List<Member>가 있어야 양쪽으로 가능함.
@OneToMany(mappedBy = "team") //일대다 매핑에서 나는 뭐랑 연결되어있지? Member 클래스의 Team 필드명.
private List<Member> memberList = new ArrayList<>();
  • Test
    - Member에 setTeam을 통해 연관관계 생성
    - DB에서 Team을 불러와서 team.getMemberList 호출 가능
    - 어? 근데 team의 memberList에 member를 추가한 적은 없는데..?
    - 연관관계의 주인은 Member이다 따라서 Team은 단순히 읽어오기만 하기 때문에. set을 안해도 조회 가능.
public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{

            Team team = new Team();
            team.setName("TeamA");
            em.persist(team); //team이 영속상태 되면 id값이 들어감.

            Member member = new Member();
            member.setUserName("member");
            
            //member에 setTeam을 통해 연관관계 생성
            member.setTeam(team);
            em.persist(member);

            em.flush(); 
            em.clear(); //캐시 삭제

			//1차 캐시 없으니, DB에서 읽어옴. 1차 캐시에 저장.
            Member findMember = em.find(Member.class, member.getId());

			//DB에서 Team을 가져와서 memberList 조회.
            List<Member> memberList = findMember.getTeam().getMemberList();
            System.out.println("==================");
            for (Member m : memberList) {

                System.out.println("member1 = " + m.getUserName());

            }
            System.out.println("==================");
            tx.commit();

        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
        }

        emf.close();

    }
==================
Hibernate: 
    select
        memberlist0_.TEAM_ID as team_id3_0_0_,
        memberlist0_.MEMBER_ID as member_i1_0_0_,
        memberlist0_.MEMBER_ID as member_i1_0_1_,
        memberlist0_.TEAM_ID as team_id3_0_1_,
        memberlist0_.USERNAME as username2_0_1_ 
    from
        Member memberlist0_ 
    where
        memberlist0_.TEAM_ID=?

member1 = member
==================

 

 

2. mappedBy


@OneToMany(mappedBy = "team") //일대다 매핑에서 나는 뭐랑 연결되어있지? Member 클래스의 Team 필드명.
private List<Member> memberList = new ArrayList<>();
  • mappedBy가 뭔데..? -> 일대 다 매핑에서 나는 상대 클래스 어느 필드(명)에 연결..?
  • 객체와 테이블간에 연관관계를 맺는 차이를 이해해야 함!!

 

 

3. 객체와 테이블이 관계를 맺는 차이


  • 객체 연관관계 = 2개 --> 단방향 연관관계 2개!
      회원 -참조-> 팀 연관관계 1개, 단방향
      팀 -참조-> 회원 연관관계 1개, 단방향
  • 테이블 연관관계 = 1개
      회원 <-FK:TEAM_ID->팀 연관관계 1개, 양방향
  • Table은 FK하나로 연관관계 끝남!

4. 객체의 양방향 관계

  • 객체의 양방향 관계는 사실 서로 다른 단방향 관계 2개임!!!!
  • 객체를 양방향으로 참조하려면! 단방향 연관관계 2개를 만들어야함!!!
A -> B  :  a.getB() Class A{
  B b;
}
B -> A  :  b.getA() Class B{
  A a;
}

 

 

 

5. Table의 연관관계


  • Table은 FK 하나로 두 테이블의 연관관계를 관리함.
  • MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계를가짐
    (양 쪽으로 JOIN 할  수 있음)
  •  MEMBER에서 TEAM_ID(FK)로 TEAM에 JOIN
    - MEMBER의 FK와 TEAM의 PK가 동인한 TABLE에 조인
SELECT * FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
  •  TEAM에서 TEAM_ID(PK)를 가지고 MEMBER에 Join
    - TEAM의 PK로 MEMBER의 FK가 동인한 TABLE에 조인
SELECT * FROM TEAM T
JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID

 

 

 

6. 그럼 둘 중에 누구의 PK를 FK로 관리해야하지..?


  • member의 team을 변경하고 싶으면...
  • team에있는 memberList를 변경해야해..? 
  • 아니면 member에서 team을 변경해야해..?
  • 하지만 DB입장에서 객체 참조를 어떻게 하던 간에 FK(TEAM_ID)값 만 업데이트 되면 됨!!!! 
  • Member -> Team 단방향 일때는 Member의 Team만 신경쓰면 되는데...
  • 양방향으로 되면서 Team의 members까지 신경 써야한다...
  • Rule을 정하면 된다. 누가 관리할지 주인을 정하자.

 

 

7. 연관관계의 주인(Owner)


  • 양방향 매핑 규칙
    • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정!
    • 연관관계의 주인 만 외래키를 관리(등록, 수정 권한 있음)
    • 주인이 아닌 쪽은 읽기만 가능
    • 주인은 mappedBy 속성 사용하지 않음!!!
    • mappedBy : 저놈에 의해 매핑이 되었어! 내가 주인이 아님.. ㅋㅋㅋ
    • 주인이 아니면 mappedBy 속성 지정!!
  • 누구를 주인으로..?
    • 외래 키가 있는 곳을 주인으로 정해라(many 쪽)
    • 여기서는 Member.team이 연관관계의 주인.
    • 주인만 등록(set), 수정이 가능!
    • 주인이 아니면 조회만 가능!
  • 왜 외래 키가 있는 곳이 주인임..?
    • DB입장에서 보면 외래 키가 있는 쪽이 항상 다(many) 측임.
    • 즉 다(many)측이 연관관계 주인임.
    • 다(many) - > @ManyToOne, @JoinColumn
    • 일(One) -> @OneToMany(mappedBy = "")
  • 연관관계 주인이 비즈니스 상으로 중요한 것은 아님.

8. GitHub : 210810 Entity Relationship


 

GitHub - bsh6463/JPA

Contribute to bsh6463/JPA development by creating an account on GitHub.

github.com

 

Comments