일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- PCCP
- DB
- 알고리즘
- SQL개발
- 정처기
- 2023년회고
- 코딩테스트
- 2024년정보처리기사
- 코딩역량인증시험
- JavaPersistenceApi
- SQL개발자시험
- 개발자
- PCSQL
- JAVA.
- 자바
- 프로그래머스
- java
- 정보처리기사대비
- springboot3
- 자바알고리즘
- 프로그래머스자바
- 코테
- python
- sql
- 정보처리기사기출
- Oracle
- JPAdata
- PCCE
- 정보처리기사
- programmers
- Today
- Total
똘이의 개발 Life
[ 자바 ORM 표준 JPA 프로그래밍 기본편 ] 세션 5 연관 관계 맵핑 기초 본문
참고 강의
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 - 인프런
저는 야생형이 아니라 학자형인가봐요^^ 활용편 넘어갔다 30% 정도 듣고 도저히 답답해서 기본편을 들어버렸네요^^. 한주 한주 김영한님 강의 들으니 렙업되는 모습을 스스로 느낍니다. 특히 실
www.inflearn.com
RDB ( 관계형 데이터 베이스 )
- 외래키를 통한 다른 테이블 참조
- 방향이 존재하지 않음.
- FK 를 통하면 양방향으로 연관관계 조회 가능
객체
- 객체를 통한 다른 객체에 대한 데이터 참조
- 양방향 객체 연관 관계를 위해서는 데이터 세팅이 필요함.
@Entity
public class Team{
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private STring name;
// = new ArrayList<>() <- 값이 없을 때 Null 값이 되는 것을 방지 하기 위한 코드
// OneTo Many 본인 객체에서 반대에 연결된 변수를 선언
@OneToMany( mappedBy = "team" )
private List<Member> members = new ArrayList<>();
...
}
mappedBy <- JPA 의 멘탈 붕괴 난이도 ( C 의 포인터 같은 존재 )
객체와 테이블 간에 연관 관계를 맺는 차이를 이해해야 한다.
객체 연관 관계 = 2개
- 회원 -> 팀 연관관계 1개
- 팀 -> 회원 연관관계 1개
단방향 연관 관계가 두 개가 있다.
테이블 연관 관계 = 1개
- FK 값
외래키 하나로 연관 관계가 해결이 된다.
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계가 2개다.
테이블의 양방향 연관관계는 FK ( 외래키 ) 값 하나로 양방향 연관 관계를 갖는다.
우리는 객체지향 언어로 application 을 개발하지만 관계형 데이터 베이스의 기조를 무시할 수 없다.
그렇기 때문에 관계형 데이터 베이스에 외래키에 대한 처치가 필요하다.
- 둘 중 하나로 외래 키를 관리해야 한다.
- 양방향 맵핑 규칙
- 객체의 두 관계중 하나를 연관관계의 주인으로 지정
- 연관관계의 주인만이 외래 키를 관리 ( 등록 , 수정 )
- 주인이 아닌 쪽은 읽기만 가능
- 주인은 mappedBy 속성 사용 X
- 주인이 아니면 mappedBy로 주인 지정 필요
mappedBy 된 곳은 조회만 가능 / 반대편은 등록 수정 가능
누구를 주인으로 ?
외래 키가 있는 곳을 주인으로 정해라
여기서는 Member.team 이 연관 관계의 주인
DB 입장에서는 1:N 일 때 N 쪽이 외래키를 갖고 있고 그렇기 때문에 N 쪽이 연관관계의 주인이 될 것 이다.
주인 개념은 비지니스 로직에 관련된 범위가 아니다.
JPA 기반 시스템 개발에 관한 개념이기 때문인 것을 인지해야 한다.
예시 )
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em.persist(member)
위와 같이 코드를 작성할 경우 insert 쿼리는 두 개가 날라가는 것을 볼 수 있다.
team 테이블 , member 테이블에 데이터는 들어가나 member table 에 team_id 가 null 것을 확인할 수 있다.
그 이유는 연관관계의 주인이 team객체에 선언되어 있기 때문이다.
값을 삽입 및 수정하기 위해서는 연관 관계의 주인에 값을 설정 해야한다.
team 에 있는 member 리스트 객체는 읽기 전용이고 수정 및 삽입을 할 수 없다.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//연관관계의 주인에 값 설정
member.setTeam(team); //**
em.persist(member)
하지만 여기 객체 지향스럽게 개발하는 방법이 있다.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
member.setTeam(team); //**
//연관관계의 주인에 값 설정
// em.persist(member); <- 이렇게 될 경우 코드를 두 줄 작성해야한다.
// 아래 setTeam 을 사용한다면 해결할 수 있다.
team.getMembers().add(member);
// 위에 setTeam 에서 문제를 해결할 수 있다.
@Entity
public class Member{
...
public void setTeam( Team team ) {
this.team = team;
// this 는 나 자신의 인스턴스
team.getMembers().add(this);
}
}
양쪽에 모든 값을 넣어주는 방식으로 개발하면 장점이 있다.
1. 주인관계에 있는 객체에만 값을 주입하고 영속성을 부여하면 DB에 들어가지 않는 이상 member list 객체에 값을 가져올 수 없다. 반면에 위와 같이 개발할 경우 양 쪽에서 데이터를 가져올 수 있다.
2. 테스트 케이스 작성 시 불편한 점을 해소해 준다.
양쪽 값 설정 시 주의해야할 점
- 연관 관계 편의 메소드 생성이 필요 ( 위의 setTeam 코드 참고 )
- 양방향 맵핑 시 무한 루프를 조심
ex) toString() , lombok , JSON 라이브러리
- lombok에서 toString() 사용 하지 말기
- JSON 같은 경우에는 controller 에는 entity 반환하지말고 DTO를 생성하여 반환하자.
아래 테이블 요구 사항이 있고 테이블 설계를 하려고 한다.
우리는 우선 순위를 아래와 같이 생각할 수 있다.
1. 단방향 관계를 우선 정의한다.
2. application 개발을 진행한다.
3. 양방향 관계가 필요할 경우 추가 개발한다.
1. 단방향 관계를 우선 정의한다.
단방향 관계는 FK 를 기준으로 정의한다.
MEMBER 테이블과 ORDERS 테이블을 봤을 때 ORDERS 테이블에 MEMBER_ID ( FK , 외래키 ) 가 있음으로
ORDERS Entity 에 단뱡항 정의를 해준다.
@Entity
@Table(name="ORDERS")
public class Orders {
@Id @GeneratedValue
@Column( name = "ORDER_ID")
private Long id;
@ManyToOne
@JoinColumn( name = "MEMBER_ID")
private Member member;
private LocalDateTime orderDate;
@Enumerated( EnumType.STRING )
private OrderStatus status;
}
위와 같이 OrderItem 객체도 세팅을 하면 된다.
2. application 개발 후 양방향 관계를 선언할지 판단.
위 조건에서는 OrderItem - Orders 에서 양방향 관계가 필요할 것이다. .
3. 양방향 관계가 필요한 경우 개발
'Back-End > JPA' 카테고리의 다른 글
JPA org.hibernate.mapping.Value.getSelectables() value is null (0) | 2024.01.23 |
---|