연관관계 매핑(단방향)
객체와 RDB는 분명 다른방향으로 동작하게 되있다. 서로 다른 패러다임을 가지고있는 객체와 RDB를 같게 만드는 것은 아무리 ORM을 사용한다고 하더라도 머리로 이해하는 것이 쉽지 않을 것이다.
JPA를 이용하여 객체와 RDB를 연결하기 위해서 몇 가지 용어를 이해해야한다.
- 방향 : 단방향, 양방향
- 다중성 : 다대일(N:1), 일다대(1:N), 일대일(1:1), 다대다(N:M)
- 연관관계의 주인 : 객체 양방향 연관관계는 관리주인이 필요
이러한 용어들을 가지고 연관관계 매핑에 대한 이해를 시작해보자.
Member와 Team을 매핑한다고 생각해보자
@Entity
class Member {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "MEMBER_ID")
private Long id;
private Long team_id;
private String usernmae;
}
@Entity
class Team {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
위의 두 테이블은 서로 다른위치에 저장된 테이블이다. 임의로 한 공간에 작성하였다.
Team team = new Team();
team.setName("myTeam");
em.persist(team);
Member member = new Member();
member.setUsername("username");
member.setTeam_id(team.getId());
em.persist(member);
연관관계의 개념에 대해서 모르는 입장에서는 이런 구조의 테이블을 매핑시켜주기 위해서 member테이블을 insert할 때 team_id를 직접 team테이블에서 가져와서 추가해준 후 insert를 해야할 것이다. 약간.. 객체지향스럽지 못한 모습이다.
조회의 경우도 마찬가지로 복잡하다.
Member findMember = em.find(Member.class, member.getId());
Long findTeam_id = findMember.getTeam_id();
Team findTeam = em.find(Team.class, findTeam_id);
member객체를 조회한 후 객체에서 team_id를 가져와서 다시 team객체를 조회해야한다. 이런 불편한 방법을 JPA의 연관관계를 이용하면 해결할 수 있다.
단방향 연관관계
한쪽에서만 한쪽을 참조할 수 있는 경우를 단방향 연관관계라고 하며 JPA에서는 어떤 관계인지에 대한 상황을 설정해주면 외래키나 매핑등을 자동으로 해주기 때문에 위에서 처럼 복잡하게 작성할 필요가 없어진다.
@Entity
class Member {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "MEMBER_ID")
private Long id;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
private String usernmae;
}
@Entity
class Team {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
기존의 코드에서 member테이블에 @ManyToOne과 @JoinColumn(name = "TEAM_ID")이 추가되었다.
Member와 Team테이블의 경우에는 N:1의 관계를 가지고 있다. 여러명의 사람이 하나의 팀에 들어갈 수 있고, 하나의 팀에 여려명의 사람이 들어갈 수 있다.
Member와 Team의 관계가 N:1관계이기 때문에 Member객체에 @ManyToOne을 설정해주는 것이다. 그리고 외래키를 어느 컬럼과 조인할지 정해줄 @JoinColumn도 설정해준다.
위와 같이 설정하면 member객체에 team_id라는 외래키가 생성이 된다.
이제 입력과 조회 시 객체지향 스럽게 수행할 수 있다.
Team team = new Team();
team.setName("myTeam");
em.persist(team);
Member member = new Member();
member.setUsername("username");
member.setTeam(team);
em.persist(member);
입력코드를 만들때도 team_id를 따로 저장하는 것이 아니라 team객체를 member객체에 그대로 넣는 것을 볼 수 있다.
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();
조회도 member객체를 가져와서 team_id를 조회한 후 team을 다시 조회하는 것이 아니라 member객체에서 바로 team객체를 가져올 수 있는 아주 객체지향 스러운 코드가 완성된다.
이처럼 코드를 짜면 member객체를 조회 할 때 team객체를 조인해서 함께 들고오게 된다.
실제로 위의 코드를 실행시켰을 떄의 쿼리이다.
이 처럼 단방향매핑을 해주면 객체지향과 RDB의 패러다임 불일치를 어느정도 해결할 수 있다.
다음에는 양방향매핑에 대해서 알아보도록 하자.
'JPA' 카테고리의 다른 글
QueryDSL 사용이유와 사용방법 (0) | 2022.06.22 |
---|---|
[JPA] 영속성 컨텍스트 (0) | 2022.02.01 |
[JPA] EntityManager (0) | 2022.02.01 |
[JPA] 프로젝트 생성 (0) | 2022.01.31 |
[JPA] JPA 알아보기 (0) | 2022.01.31 |
댓글
이 글 공유하기
다른 글
-
QueryDSL 사용이유와 사용방법
QueryDSL 사용이유와 사용방법
2022.06.22 -
[JPA] 영속성 컨텍스트
[JPA] 영속성 컨텍스트
2022.02.01 -
[JPA] EntityManager
[JPA] EntityManager
2022.02.01 -
[JPA] 프로젝트 생성
[JPA] 프로젝트 생성
2022.01.31