※ 인프런 강의 김영한님의 「자바 ORM 표준 JPA 프로그래밍」을 학습한 내용을 정리한 글입니다.
- 객체와 테이블 연관관계의 차이를 이해
- 객체의 참조와 테이블의 외래 키를 매핑
- 방향(Direction) : 엔티티의 관계가 어느쪽을 참조하고 있는지
- 단방향 : 엔티티의 관계가 한 쪽만 참조하는 것
ex) 회원 → 팀, 팀 → 회원 - 양방향 : 엔티티의 관계가 양쪽 모두 참조하는 것
ex) 회원 ↔ 팀
- 단방향 : 엔티티의 관계가 한 쪽만 참조하는 것
- 다중성(Multiplicity) : 연관 관계가 있는 여러 개의 클래스가 있을 때 실제로 연관을 가지는 객체의 수
- 다대일(N:1) ex) 회원(N) : 팀(1)
- 일대다(1:N) ex) 팀(1) : 회원(N)
- 일대일(1:1)
- 다대다(N:N)
- 연관관계의 주인(Owner) : 객체가 양방향 연관관계일 때 테이블의 외래키를 관리하는 객체
단방향 연관관계
<예제 프로젝트 구상>
1. 회원과 팀이 있다.
2. 회원은 하나의 팀에만 소속될 수 있다.
3. 회원과 팀은 다대일 관계이다.
회원(Member)과 팀(Team) 객체의 연관관계
@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;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
// getter/setter 생략
}
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
// getter/setter 생략
}
Main.java
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeam(team);
em.persist(member);
// Member 정보를 영속성 컨텍스트에서 찾지 않고, DB에서 찾아오는 쿼리문을 보고싶을 때
em.flush(); // 현재 영속성 컨텍스트의 내용을 모두 DB 쿼리로 날림
em.clear(); // 영속성 컨텍스트 초기화
Member findMember = em.find(Member.class, member.getId());
// (1) Member 객체 일일이 찾아서 넣어줌
//Long findTeamId = findMember.getTeamId();
//Team findTeam = em.find(Team.class, findTeamId);
// (2) 단방향 매핑 후 조회, (1)을 보완한 것
Team findTeam = findMember.getTeam();
// (3) 수정
Team newTeam = em.find(Team.class, 100L); // PK가 100인 팀 객체 찾기
findMember.setTeam(newTeam); // DB에 외래키 값 변경됨
- 회원 객체는 Member.team 필드(멤버변수)로 팀 객체와 연관관계를 맺음
- 회원 객체와 팀 객체는 단방향 관계
→ 회원은 Member.team 필드를 통해 팀을 알 수 있지만, 반대로 팀은 회원을 알 수 없음
ex) member → team : member.getTeam()
ex) team → member : x
- @ManyToOne
- 다대일(N:1) 관계를 나타내는 매핑 정보
- 연관관계 매핑 시 사용 필수
- 속성
속성 설명 기본값 optional false로 설정 시 연관된 엔티티가 항상 존재해야 함 true fetch 글로벌 패치 전략 설정 FetchType.EAGER cascade 속성 전이 기능 사용 targetEntity ◾ 연관된 엔티티의 타입 정보 설정
◾ 거의 사용하지 않음
◾ 컬렉션 사용해도 제네릭으로 타입 정보 알 수 있음
ex) @OneToMany
private List<Member> members;
- @JoinColumn
- 외래 키 매핑 시 사용
- 생략 가능
- 속성
속성 설명 기본값 name 매핑할 외래 키 이름 필드명 + _ + 참조하는 테이블의
기본 키 컬럼명
ex) team_TEAM_IDreferencedColumnName 외래 키가 참조하는
대상 테이블의 컬럼명참조하는 테이블의 기본 키 컬럼명 foreignKey
(DDL)◾ 외래 키 제약조건 직접 지정
◾ 테이블 생성 시에만 사용unique,
nullable,
insertable,
columnDefinition,
table@Column의 속성과 같음
회원(Member)과 팀(Team) 테이블 연관관계
- 회원 테이블은 TEAM_ID 외래 키로 팀 테이블과 연관관계를 맺음
- 회원 테이블과 팀 테이블은 양방향 관계
→ 회원 테이블의 TEAM_ID 외래키를 통해 회원과 팀, 팀과 회원 조인 가능- 회원(MEMBER)과 팀(TEAM) 조인
- SELECT * FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM.ID
- 팀(TEAM)과 회원(MEMBER) 조인
- SELECT * FROM TEAM T JOIN MEMBER M ON T.TEAM_ID = M.TEAM.ID
- 회원(MEMBER)과 팀(TEAM) 조인
🔅 객체 연관관계 vs 테이블 연관관계
- 객체는 참조(주소)로, 테이블은 외래 키로 조인을 사용해서 연관관계를 맺는다.
- 객체의 연관관계는 단방향(A → B (a.b)), 테이블의 연관관계는 양방향(A JOIN B, B JOIN A)이다.
- 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
- A → B (a.b)
- B → A (b.a)
'JPA' 카테고리의 다른 글
[JPA] 다양한 연관관계 매핑 (0) | 2022.11.28 |
---|---|
[JPA] 연관관계 매핑 - 양방향 연관관계 (0) | 2022.08.08 |
[JPA] 엔티티 매핑 (0) | 2022.07.28 |
[JPA] 준영속 상태 (0) | 2022.07.18 |
[JPA] 플러시(Flush) (0) | 2022.07.18 |
댓글