반응형
단방향 연관관계
객체 연관관계 와 table 관계
@Entity
public class User {
@Id
@Column(name = "user_id")
private Long id;
private String username;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="team_id")
private Team team;
}
@Entity
public class Team {
@Id
@Column(name = "team_id")
private Long id;
private String name;
}
객체
- user는 team을 참조 할 수 있지만, team은 user를 참조할 수 없음
- 연관 관계 : 필드 접근 -> user.getTeam() 을 사용해서 접근
table
- 외래키를 사용해서 양방향으로 join할 수 있음
- join을사용해서 연관 관계 접근
select * from user inner join team on user.team_id = team.team_id;
Annotation
@JoinColumn
1.name
- 기능 : mapping할 외래키 이름
- 기본 값 :
${필드면}_${table.pk_column_name}
- referencedColumnName
- 기능 : 외래 키가 참조하는 대상 table 컬럼 명
- 기본 값 : 참조하는 table의 기본 key 컬럼 명
- foreignKey(DDL)
- 기능 : 외래키 제약조건을 직접 지정, 테이블 사용할 때만 사용
- unique, nullable, insertable, updateable, columnDefinition, table -> @Column의 속성과 동일
@ManyToOne
- optional
- 기능 : table로 설정하면 연관된 엔티티가 항상 있어야합니다.
- 기본값 : true
- fetch
- 기능 : fetch 전략을 설정
- 기본값
- @ManyToOne : EAGER
- @OneToMany : LAZY
- cascade
- 기능 : 연관 entity에게 전달하는 option 정보를 담는다
- targetEntity
- 기능 : 연관된 Entity의 타입 정보를 설정, Collection 사용해서 generic으로 타입 정볼르 넣어줄 수 있음
@OneToMany(targetEntity=User.class)
private List users;
연관관계 기능들
저장
- 저장 로직
public void testSave() {
// team1 저장
Team team1 = new Team("team1", "팀1");
em.perist(team1);
// 회원 1 저장
User user1 = new User("user1", "회원1");
user1.setTeam(team1);
em.persist(user1);
User user2 = new User("user2", "회원2");
user2.setTeam(team1);
em.persist(user2);
}
- 실제 SQL실행 결과
insert into team (team_id, name) values('team1', '팀1');
insert into users(users_id, name, team_id) values('user1', '회원1', 'team1');
insert into users(users_id, name, team_id) values('user2', '회원2', 'team1');
조회
- 조회 방법
- 그래프 탐색
- JPQL 사용
- 그래프 탐색
User user = em.find(User.class, "user1");
Team team = user.getTeam(); // 객체 그래프 탐색 시작 -> sql이 나가는 시점
- JPQL
- 기본적인 inner join으로 조회
void queryLoginJoin(EntityManager em) {
String jpql = "select u from User u join m.team t where t.name=:teamName";
List<User> users = em.createQuery(jpql, User.class)
.getResultList(); // 여기서 바로 조회
// ... codes
}
- jpql에서 객체 들이 전부 table에 최적화된 sql으로 변환
수정
- 수정 방법 : snapshot을 이용해서 변경
void updateRelation(EntityManager em) {
Team team2 = new Team("team2", "팀2");
em.persist(team2);
User user = em.find(User.class, "user1");
user.setTeam(team2);
}
- 실행 sql
update user set team_id = 'team2' where user_id='user1';
- 위와 같이 set 함수를 사용해서 연관 관계를 변경할 수 있습니다.
제거
void deleteRelation(EntityManager em) {
User user = em.find(User.class, "user1");
user.setTeam(null); // 연관 관계 제거
}
연관 관계 엔티티 삭제
- 순서
- 기존에 연관관계 끊기
- 연관관계 entity삭제
- 이유
- 외래키 제약조건 때문에 삭제 이슈발생할 수 있음
user1.setTeam(null);
user2.setTeam(null);
em.remove(team1);
양방향 연관관계
패러다임 불일치
테이블은 외래키를 사용해서 양방향을 JOIN으로 조히할 수 있음, table은 양방향 관계가 아닌 단방향 관계가 2개가 이어진 경우
- 문제점 : 어느 객체를 기준을 잡고 외래키를 update할지 의문을 가져아함
- 해결법 : 둘중에 하나를 기준으로 설정하고, 기준이 아닌 관계는 거울인 mappedby라는 키워드를 사용한다.
mapping 방법
@Entity
public class User {
@Id
@Column(name = "user_id")
private String id;
private String username;
@JoinColumn(name = "team_id")
@ManyToOne(fetch = FetchType.LAZY)
private Team team;
}
@Entity
public class Team {
@Id
@Column(name="team_id")
private String id;
private String name;
@OneToMany(mappedBy="team")
private List<Member>
}
- 연관 관계의 주인을 설정하는 방법 : 외래키를 가지고 있는 entity를 기준으로 잡는게 좋음 -> DB구조를 확인할 수 있기 때문에 좋음
- 연관관계의 주인 : User가 된다. -> user가 team의 id 를 외래키로 가지고 있기 때문
- mappedby : 연관관계에서 주인이 아닌 객체를 나타내기 위해서 사용한다.
- 연과관계 주인은 mappedby를 사용하지 않는다.
양방향 연관관계시 주의점
객체에서도 양방향 관계가 적절하게 이뤄지는지 확인하기
- 연관과계를 맺었더라도, 객체에서도 값이 잘 입력 되어 있는지 확인하는게 안전다하.
- user1 : team1 가지고 있음
- team1 : user2, user3을 가짐
- -> table상에서는 user1과 team1은 연관관계이다 하지만 객체 상으로 아니다 그렇기 때문에 연관관계 편의 메소드가 필요
연곤관계 편의 메소드
- 정의 : 양방향 관계에서 연관관계를 맺을 때 객체까지도 양방향 관계를 유지하기 위해서 사용하는 메소드
- 예 : User함수
private void withdrawFromTeam() { team.users.remove(this); this.team = null; }
private void changeTeam(Team team) {
withdrawFromTeam(); // 연관관계 제거
team.users.add(this);
this.team = team;
}
```
- team을 바꾸더라도 기존에 남아 있는 연관관계를 제거 해줘야 한다.
- team1 -> team2로 바꾼다고 할때 team1에 user1이 계속 남아있을 수 있음
반응형
'JPA > ORM 표준 JPA' 카테고리의 다른 글
Fetch Join 별칭 이슈 (2) | 2022.01.22 |
---|---|
06 연관관계 Mapping 종류 (2) | 2021.08.21 |
04 Entity (3) | 2021.07.08 |
03. 영속성 (0) | 2021.06.30 |
02. JPA 요소들 (2) | 2021.06.29 |