참고 강의 : [토크ON세미나] JPA 프로그래밍 기본기 다지기

@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name="USERNAME")
private String name;
private int age;
@Column(name="TEAM_ID")
private Long teamId;
...
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
...
//팀 저장
Team team=new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member=new Member();
member.setName("member1");
member.setTeamId(team.getId());
em.persist(member);
//조회
Member findMember=em.find(Member.class,member.getId());
//연관관계가 없음
Team findTeam=em.find(Team.class,team.getId());
객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.
- 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
- 객체는 참조를 사용해서 연관된 객체를 찾는다.
- 테이블과 객체 사이에는 이러한 큰 간격이 있다.

@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name="USERNAME")
private String name;
private int age;
//@Column(name="TEAM_ID")
//private Long teamId;
@ManyToOne //연관관계 (멤버 입장)
@JoinColumn(name="Team_ID") //적어주는 것이 좋음
private Team team;
...
}

//팀 저장
Team team=new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
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();

@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy="team")
List<member> members=new ArrayList<Member>();
...
//조회
Team findTeam=em.find(Team.class,team.getId());
int memberSize=findTeam.getMembers().size(); //역방향 조회
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개이다.
객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
A -> B (a.getB()) class A { B b; }
B -> A (b.getA()) class B { A a; }
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

둘 중 하나로 외래 키를 관리해야 한다. = 둘 중의 하나의 객체로만 업데이트할 수 있고 나머지 하나는 조회만 가능하다.

Team team=new Team();
team.setName("TeamA");
em.persist(team);
Member memeber = new Member();
member.setName("member1");
//역방향 (주인이 아닌 방향)만 연관관계 설정 (어차피 무시됨)
team.getMembers().add(member);
em.persist(member);

member.setTeam(team);
//정방향(주인)이 연관관계가 설정 되어야 함.
가 추가 되어야 정상 저장 됨.
실제 코드에서는 항상 양쪽 다 값을 입력하는 것을 권장
연관관계 매핑 어노테이션
- 다대일 (@ManyToOne)
- 일대다 (@OneToMany)
- 일대일 (@OneToOne)
- 다대다 (@ManyToMany)
- @JoinColumn, @JoinTable
상속관계 매핑 어노테이션
- @Inheritance
- @DiscriminatorColumn
- @DiscriminatorValue
- @MappedSuperclass (매핑 속성만 상속)
복합키 어노테이션
- @IdClass
- @EmbeddedId
- @Embeddable
- @MapsId