두 테이블을 연결하는 데 사용되는 키
자식 테이블 - 외래키가 포함된 테이블
부모 테이블 - 외래키를 제공하는 테이블
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team); // PK 값이 세팅된 상태
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeamId(team.getId()); // 외래키 식별자를 직접 다룸
em.persist(member);
객체를 테이블에 맞춰 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team); // PK 값이 세팅된 상태
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeam(team); // 단방향 연관관계 설정, 참조 저장
em.persist(member);
-------------------------------------------
// 조회
Member findMember = em.find(Member.class, member.getId());
// 참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam();
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<>();
Team findTeam = em.find(Team.class, team.getId());
int memberSize = findTeam.getMembers().size();
select * from member m
join team t on m.team_id = t.team_id;
select * from team t
join member m on t.team_id = m.team_id;
@ManyToOne
- 다 대 일@OneToMany
- 일 대 다mappedBy
="이름" 이름은 반대쪽 매핑의 필드이름 값으로 준다.Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//역방향(주인이 아닌 방향)만 연관관계 설정
// 주인이 아니기 때문에 null 값이 나올 수 있다.
team.getMembers().add(member);
em.persist(member)
옳은 것(순수한 객체 관리를 고려하면 항상 양쪽 값 다 입력해야 함)
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
team.getMembers().add(member);
//연관관계의 주인에 값 설정
member.setTeam(team);
em.persist(member);
💡단방향 매핑만으로도 이미 연관관계 매핑완료
양방향은 조회(객체 그래프 탐색) 기능 추가된 것
JPQL에서 역방향 탐색할 일 많음
단방향 매핑 잘하고 양방향은 필요할 때 추가(테이블 영향 X)
@ManyToOne
@OneToMany
@OneToOne
@ManyToMany
- 실무에서 사용 X💡객체 양방향 관계에서 연관관계의 주인은 항상 '다' 쪽이다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne // Member와 Team의 관계 : 다대일 단방향
@JoinColumn(name = "TEAM_ID") //Team team이 조인(매핑)하는 컬럼은 TEAM_ID이다(통상적 기본키를 받아옴)
private Team team;
양방향
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "Member_ID")
private Long id;
private String username;
@OneToMany(mappedBy = "team") //1대다 매핑에서 반대편 사이드 Member의 team이 걸려있다.
private List<Member> members = new ArrayList<Member>(); //단순히 조회만 가능하다
@Column(name = "TEAM_ID")
private Long teamID;
단방향
@JoinColumn
을 꼭 사용. 그렇지 않을 시 중간 테이블 하나 추가됨@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String username;
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
양방향
@JoinColumn(insertable=false, updatable=false)
사용(읽기전용필드)@Entity
public class Team {
...
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
-----------------------------------------
@Entity
public class Member {
...
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false) //읽기전용
private Team team;
public void changeTeam(Team team) { //연관관계 편의 메서드
this.team = team;
team.getMembers().add(this);
}
@ManyToOne
단방향과 유사@ManyToMany
사용@JoinTable
연결 테이블 지정@ManyToMany
-> @OneToMany
, @ManyToOne