
Direction): 단방향, 양방향Multiplicity): 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)Owner): 객체 양방향 연관관계는 관리 주인이 필요@Entity
public class Member {
@Id
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private Long teamId;
}
@Entity
public class Team {
@Id
@GeneratedValue
private Long id;
private String name;
}
//조회
Member findMember = em.find(Member.class, member.getId());
//연관관계가 없음
Team findTeam = em.find(Team.class, team.getId());
테이블 : 외래키 조인 vs 객체 : 참조객체 그래프 탐색 : 객체는 참조를 사용해 연관관계를 탐색조인 : DB는 외래 키를 사용해 연관관계를 탐색@Entity
public class Member {
@Id
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@JoinColumn(name = "TEAM_ID")외래 키를 매핑할 때 사용한다.name 속성에는 매핑할 외래 키 이름을 지정한다.TEAM_ID 외래 키로 연관관계를 맺으므로 이 값을 지정하면 된다.필드명 + _ + 참조하는 테이블의 기본 키 컬럼명team_TEAM_IDpublic class MainJPA {
public static void main(String[] args) {
//팀 저장
Team team = new Team("TeamA");
em.persist(team);
//회원 저장
Member member = new Member("member1", team); //단방향 연관관계 설정, 참조 저장
em.persist(member);
//조회
Long id = member.getId();
Member findMember = em.find(Member.class, id);
//참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam();
// 새로운 팀B
Team teamB = new Team("TeamB");
em.persist(teamB);
// 회원1에 새로운 팀B 설정
member.setTeam(teamB);
}
}
@Entity
public class Member {
@Id
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@Entity
public class Team {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
}
@OneToMany(mappedBy = "team")
- 객체 : 사실 2개의 단방향 연관관계
- 테이블 : PK, FK를 통해 양방향 연관관계
Member 객체 자체와 테이블 매핑 vs Team 속 members 리스트를 통해 테이블 매핑
- 만약
Member객체는 그대로 인데members리스트는 빈 리스트이면???- 둘중 뭐로 매핑할지 정해야 함
Owner)위의 두 관계 중 하나만 연관관계 주인으로 설정
외래키가 있는 쪽이 주인!!!(team)
n 쪽주인의 반대편, PK 있는 쪽(members)
1 쪽mappedBy 속성 사용!@OneToMany(mappedBy = "team")class Main {
public static void main(String[] args) {
Team team = new Team("TeamA");
em.persist(team);
// 1. 역방향(주인이 아닌 방향)만 연관관계 설정
Member member = new Member("member1");
team.getMembers().add(member);
em.persist(member);
// 오류!!!
// 2. 연관관계 주인 방향도 값 설정
Member member = new Member("member1", team);
team.getMembers().add(member);
em.persist(member);
// 정상 작동!!!
}
}
주인값, 비 주인값(리스트) 꼭 입력해야 함항상 양쪽에 값을 설정하자!@Entity
public class Member {
//...
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);// !!!!
}
}
Team.addMembers(team) 형태로 만들기도 함연관관계 변경 시 기존 연관관계가 있으면, 해당 관계를 삭제하는 코드를 추가해야 함!!toString()member{team{member{team{...}}}}
JSON 변환시 자주 발생JSON 관련 라이브러리에서 제공하는 어노테이션/기능을 써 해결 가능lombok에서는 toString() 쓰지마라!entity를 반환하는 대신 DTO 를 사용해라[책, 강의] 자바 ORM 표준 JPA 프로그래밍(김영한)