단방향 연관관계
- 객체 연관관계 : 회원 객체와 팀 객체는 단방향 관계다. => 회원은 Member.team 필드를 통해서 팀을 알 수 있지만 반대로 팀은 회원을 알 수 없다.
- 테이블 연관관계 : 회원 테이블과 팀 테이블은 양방향 관계다. 회원 테이블의 TEAM_ID 외래 키를 통해서 회원과 팀을 조인할 수 있고 반대로 팀과 회원도 조인할 수 있다.
- 객체 연관관계와 테이블 연관관계의 가장 큰 차이
- 참조를 통한 연관관계는 언제나 단방향이다. 객체 간에 연관관계를 양방향으로 만들고 싶으면 반대쪽에도 필드를 추가해서 참조를 보관해야 한다. => 정확히 이야기하면 이것은 양방향 관계가 아니라 서로 다른 단방향 관계 2개다.
객체 연관관계 VS 테이블 연관관계 정리
- 객체는 참조(주소)로 연관관계를 맺는다.
- 테이블은 외래 키로 연관관계를 맺는다.
- 참조를 사용하는 객체의 연관관계는 단방향이다. (A -> B)
- 외래 키를 사용하는 테이블의 연관관계는 양방향이다. (A JOIN B 가 가능하면 B JOIN A도 가능하다.)
- 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
순수한 객체 연관관계
public class Main {
public static void main(String[] args) {
Member member1 = new Member("member1", "회원1");
Member member2 = new Member("member2", "회원2");
Team team1 = new Team("team1", "팀1");
member1.setTeam(team1);
member2.setTeam(team1);
Team findTeam = member1.getTeam();
}
}
@Getter
@Setter
public class Member {
private String id;
private String username;
private Team team; // 팀의 참조를 보관
}
@Getter
@Setter
public class Team {
private String id;
private String name;
}
- 객체는 참조를 사용해서 연관관계를 탐색할 수 있는데 이것을 객체 그래프 탐색이라 한다.
테이블 연관관계
CRAETE TABLE MEMBER {
MEMBER_ID VARCHAR(255) NOT NULL,
TEAM_ID VARCHAR(255),
USERNAME VARCHAR(255),
PRIMARY KEY (MEMBER_ID)
}
CREATE TABLE TEAM {
TEAM_ID VARCHAR(255) NOT NULL,
NAME VARCHAR(255),
PRIMARY KEY (TEAM_ID)
}
ALTER TABLE MEMBER ADD CONSTRAINT FK_MEMBER_TEAM
FOREIGN KEY (TEAM_ID)
REFERENCES TEAM
# 회원1과 회원2를 팀1에 소속시킨다.
INSERT INTO TEAM(TEAM_ID, NAME) VALUES('team1', '팀1');
INSERT INTO MEMBER(MEMBER_ID, TEAM_ID, USERNAME)
VALUES('member1', 'team1', '회원1');
INSERT INTO MEMBER(MEMBER_ID, TEAM_ID, USERNAME)
VALUES('member2', 'team1', '회원2');
# 회원1이 소속된 팀 조회
SELECT t.*
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
WHERE M.MEMBER_ID = 'member1'
- 데이터에비으스는 외래 키를 사용해서 연관관계를 탐색할 수 있는데 이것을 조인이라 한다.
객체 관계 매핑
매핑한 회원 엔티티
@Entity
public class Member {
@Id
private String id;
@ManyToOne // 연관관계 매핑
@JoinColumn(name="TEAM_ID")
private Team team;
public void setTeam(TEam team) {
this.tema = team;
}
,,,
}
매핑한 팀 엔티티
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private String id;
private String name;
...
}
- @ManyToOne : 이름 그대로 다대일 관계라는 매핑 정보다. 연관관계를 매핑할 때 이렇게 다중성을 나타내는 어노테이션을 필수로 사용해야 한다.
- @JoinColumn(name="TEAM_ID") : 외래 키를 매핑할 때 사용한다. name 속성에는 매핑할 외래 키 이름을 지정한다. 이 어노테이션은 생략할 수 있다.
@JoinColumn
<주요 속성>
- name : 매핑할 외래 키 이름
- referencedColumnName : 외래 키가 참조하는 대상 테이블의 컬럼명
- foreignKey(DDL) : 외래 키 제약조건을 직접 지정할 수 있다. 이 속성은 테이블을 생성할 때만 사용한다.
- unique, nullable, insertable, updatable, columnDefinition, table : @Column의 속성과 같다.
- @JoinColumn을 생략하면 기본 전략을 사용하여 외래 키를 찾는다.
- 기본 전략 : '필드명_참조하는 테이블의 컬럼명'
@ManyToOne
<주요 속성>
- optional : false로 설정하면 연관된 엔티티가 항상 있어야 한다.
- fetch : 글로벌 패치 전략을 설정한다.(FetchType.EAGER, FetchType.LAZY)
- cascade : 영속성 전이 기능을 사용한다.
- targetEntity : 연관된 엔티티의 타입 정보를 설정한다.(이 기능은 거의 사용하지 않는다.)
'공부 기록 > Java' 카테고리의 다른 글
[이펙티브 자바 3/E] 아이템14 - Comparable을 구현할지 고려하라 (0) | 2023.08.09 |
---|---|
[이펙티브 자바 3/E] 아이템13 - clone 재정의는 주의해서 진행하라 (0) | 2023.08.09 |
[이펙티브 자바 3/E] 아이템12 - toString을 항상 재정의하라 (0) | 2023.07.31 |
[이펙티브 자바 3/E] 아이템11 - equals를 재정의하려거든 hashCode도 재정의하라 (0) | 2023.07.31 |
[JPA] 4장 - 엔티티 매핑(2) - 필드와 컬럼 매핑 (0) | 2023.07.31 |