2021. 2. 3. 22:59ㆍ프로그래밍 언어/Spring Framework
[인프런 김영한] 연관관계 매핑 기초 - 양방향 연관관계
해당 글은 인프런 김영한강사님의 영상을 보고 정리한 글입니다.
Spring Boot, Spring Data JPA를 사용해 실습하였습니다.
김영한 인프런 : www.inflearn.com/users/@yh
▣ Goal
1. 양방향 연관관계
2. 연관관계의 주인
▣ 문제
public JpaApplication(TeamRepository teamRepository, MemberRepository memberRepository) {
this.teamRepository = teamRepository;
this.memberRepository = memberRepository;
Team team = new Team();
team.setName("TeamA");
teamRepository.save(team);
Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
memberRepository.save(member);
Member findMember = memberRepository.findById(member.getId()).get();
Team findTeam = findMember.getTeam();
// Team에서 member를 볼 수 없을까? -> 양방향
findTeam.getMember(); // Error
System.out.println("findTeam = " + findTeam.getName());
}
| Member의 Team을 조회는 가능했다. (findMember)
그러면 반대로 Team에서 Member 조회는 안될까? (지금은 안됨)
▣ 단방향에서 양방향으로 변경할 때 (테이블 연관관계 , 객체 연관관계)
| 단방향에서 양방향으로 관계매핑을 할 때 [테이블 연관관계]에서는 전혀 변화가 없다. (FK로 끝)
[객체 연관관계]에서는 Team에 List<Member>를 넣어주어야 한다. Team은 Member를 모르기 때문.
▣ 단방향 -> 양방향
@Entity
@Setter
@Getter
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
// 코드 추가
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
}
@Entity
@Setter
@Getter
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
* @OneToMany : One은 Team, Many는 Member를 의미
* mappedBy : Member의 @ManyToOne에 해당하는 Team team 이라는 변수명을 적어준다.
매핑되는 객체에서 "team과 매핑이 된다" 라고 생각하면된다.
▶ 끝이다. 반대로 탐색이 가능하다.
▣ 예제
@SpringBootApplication
public class JpaApplication {
public static void main(String[] args) {
SpringApplication.run(JpaApplication.class, args);
}
private static TeamRepository teamRepository;
private static MemberRepository memberRepository;
public JpaApplication(TeamRepository teamRepository, MemberRepository memberRepository) {
this.teamRepository = teamRepository;
this.memberRepository = memberRepository;
Team team = new Team();
team.setName("TeamA");
teamRepository.save(team);
Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
memberRepository.save(member);
// 예제 핵심포인트
Member findMember = memberRepository.findById(member.getId()).get();
List<Member> members = findMember.getTeam().getMembers(); // member에서 team을 찾고 team의 member를 찾는다.
for (Member m : members) {
System.out.println("member = " + m.getUsername());
}
}
}
``````````````````````````````````````````````````````````````````````````````````
// SQL문
Hibernate:
select
member0_.member_id as member_i1_0_0_,
member0_.team_id as team_id3_0_0_,
member0_.username as username2_0_0_,
team1_.team_id as team_id1_1_1_,
team1_.name as name2_1_1_
from
member member0_
left outer join
team team1_
on member0_.team_id=team1_.team_id
where
member0_.member_id=?
Hibernate:
select
members0_.team_id as team_id3_0_0_,
members0_.member_id as member_i1_0_0_,
members0_.member_id as member_i1_0_1_,
members0_.team_id as team_id3_0_1_,
members0_.username as username2_0_1_
from
member members0_
where
members0_.team_id=?
member = member1
T※ Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.
에러가 발생할 시 Team의 private List<Member> members = new ArrayList<>();에
@OneToMany(mappedBy = "team", fetch = FetchType.EAGER)를 추가한다.
** Eager는 차후 영상 듣고 내용추가하기
▣ 그래서 양방향이 좋은건가?
-> 기본적으로 단방향이 좋다. 양방향은 신경쓸께 많다.
▣ 양방향관계, 객체와 테이블이 관계를 맺는 차이
[객체 연관관계] = 2개
회원 -> 팀 (1개, 단방향)
팀 -> 회원 (1개, 단방향)
▶ 객체의 양방향 관계는 서로 다른 단방향 관계 2개이다.
▶ 객체는 둘중(MEMBER, TEAM) 하나로 왜래키를 관리해야 한다. -> 연관관계의 주인을 정해야 한다.
[테이블 연관관계] = 1개
회원 <-> 팀 (1개, 양방향)
▣ 연관관계의 주인을 정해야 한다.
* 양방향 매핑 규칙
1. 객체의 두 관계중 하나를 연관관계의 주인으로 지정
2. 견관관계의 주인만이 왜래키를 관리(등록, 수정)
3. 주인이 아닌쪽은 읽기만 가능
4. 주인은 mappedBy 속성 사용X
5. 주인이 아니면 mappedBy 속성으로 주인 지정
▣ 그래서 누구를 주인으로 할까?
| 여기서는 Member.team이 연관관계 주인. 테이블 연관관계에서 FK를 생각하면 조금 더 쉽다.
'프로그래밍 언어 > Spring Framework' 카테고리의 다른 글
[인프런 김영한] 연관관계 매핑 기초 - 단방향 연관관계 (0) | 2021.02.04 |
---|---|
[인프런 김영한] 연관관계 매핑 기초 - 양방향 연관관계 매핑시 가장 많이 하는 실수 (0) | 2021.02.04 |
스프링 AOP 용어 , 스프링 네임스페이스 (0) | 2018.01.18 |
토비의 스프링 3.1 - 싱글톤, 싱글톤 패턴 (0) | 2017.12.21 |
객체지향 설계 5대 원칙 (SOLID) (0) | 2017.12.21 |