일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- DP
- deque
- Java
- mvc
- 연관관계
- appendleft
- 그리디 알고리즘
- 프로그래머스
- 소수판별
- python3
- c#
- BFS
- 소수찾기
- 우선순위큐
- 브루투포스
- 백준
- 합 구하기
- JPA
- 파이썬
- pypy3
- 인프런
- 완전탐색
- C#강의
- spring
- popleft
- 1일1솔
- unity
- Python
- LCM
- 누적합
- Today
- Total
jae_coding
[Spring JPA] 연관관계 매핑 본문
목차
- 단방향 연관관계
- 양방향 연관관계와 연관관계의 주인
목표
- 객체와 테이블 연관관계의 차이에 대한 이해
- 객체의 참조와 테이블의 외래 키 매핑
- 방향, 다중성, 연관관계의 주인에 대한 용어 이해
0. 예제 시나리오
- 회원과 팀이 있다.
- 회원은 하나의 팀에만 소속될 수 있다.
- 회원과 팀은 다대일 관계이다.
- 객체 Diagram
- 테이블 Diagram
1. 단방향 연관관계
Member Entity
package hellojpa;
import javax.persistence.*;
import java.util.Date;
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id;
@Column(name = "username")
private String username;
@Column(name = "team_id")
private Long teamId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getTeamId() {
return teamId;
}
public void setTeamId(Long teamId) {
this.teamId = teamId;
}
}
Team Entity
package hellojpa;
import javax.persistence.*;
@Entity
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "team_id", nullable = false)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Main
package hellojpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class jpaMain {
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);
//멤버 저장
Member member = new Member();
member.setUsername("memberA");
member.setTeamId(team.getId());
em.persist(member);
tx.commit();
} catch (Exception e){
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
DB Checking
조회 기능 (객체지향스럽지 않음)
//멤버 조회
Member findMember = em.find(Member.class, member.getId());
Long findTeamId = findMember.getTeamId();
Team findTeam = em.find(Team.class, findTeamId);
테이블에 대한 모델링을 하지 않으면 협력 관계를 만들 수 없다.
객체와 테이블 사이에는 외래 키와 참조에 대한 차이점이 존재한다.
단방향 연관관계를 이용한 해결방법
Member: Many, Team: One의 관계로 JoinColumn.
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
//멤버 저장
Member member = new Member();
member.setUsername("memberA");
member.setTeam(team);
em.persist(member);
//멤버 조회
Member findMember = em.find(Member.class, member.getId());
Team findTeam = em.find(Team.class, findMember.getTeam());
결과: 팀의 id없이 바로 team객체 조회 가능
더욱 객체지향스러운 코드로 변경이 완료된 것을 확인 할 수 있다.
2. 양방향 연관관계와 연관관계의 주인
매우 중요 !! 배경(객체 (참조), 테이블(외래 키) 패러다임 차이를 이해해야함)
예제를 업그레이드하는 방식으로 진행
- 객체 Diagram
- 테이블 Diagram
객체의 입장에서는 Team에 member 리스트를 넣어주어야 양쪽으로 참조를 할 수 있다.
하지만, 테이블의 입장에서는 member에서 외래키를 주어준다면 양쪽으로 연관관계를 지닐 수 있다.
따라서 아래와 같이 리스트를 생성해주어야 한다.
Team
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
Main
//팀 멤버 조회
List<Member> members = findMember.getTeam().getMembers();
for (Member m : members) {
System.out.println("m.getUsername() = " + m.getUsername());
}
mappedBy를 왜, 언제 사용하는 것인가?
객체와 테이블에 연관관계를 맺는 차이를 이해해야 한다.
- 객체 연관관계 (2개)
- 회원 👉 팀 (단방향)
- 팀 👉 회원 (단방향)
객체의 양방향 관관계는 사실상 양방향 연관관계가 아닌 단방향 연관관계가 2개 있다는 것이다.
팀, 회원 중 하나만으로 외래 키를 관리해야한다 👉 연관관계의 주인이 필요하다 !
☝️연관관계의 주인만이 외래 키를 관리 (등록, 수정)
✌️주인이 아닌 쪽은 읽기만 가능 (mappedby)
주인: mappedBy사용 x, 주인이 아닌쪽 mappedBy사용
연관관계의 주인은 누구?
🌟 외래키가 있는 곳을 주인으로 해야한다.
DB를 보면, 외래키가 있는 곳이 N(다) 외래키가 없는곳이 1이다. (ManyToOne에서는 Many가 연관관계의 주인, One쪽은 mappedBy)
2. 테이블 연관관계 (1개)
회원 👈👉 팀 (양방향)
테이블은 외래 키 하나를 통해서 두 테이블의 연관관계를 관리해준다.
'Spring, java > Spring_JPA' 카테고리의 다른 글
[Spring JPA] 상속관계 매핑 (Superclass) (0) | 2022.09.13 |
---|---|
[Spring JPA] 다양한 연관관계 매핑 (N:1, 1:N, 1:1, N:M) (0) | 2022.09.10 |
[Spring JPA] 엔티티 매핑 (0) | 2022.09.08 |
[Spring JPA] 영속성 관리 (영속성 컨텍스트) (0) | 2022.09.08 |
[Spring JPA] Hello 순수JPA (0) | 2022.09.08 |