jpaitem 프로젝트

전영덕·2023년 5월 1일
0

Springboot

목록 보기
10/13

----day10
com.codingbox.jpaitem라는 새로운 프로젝트 만든다.

롬복, 오라클 드라이버, 스프링 데이터 JPA 이 3가지 드라이버만 가지고 온다.

오늘 배운 걸로 시험볼 것이다.

똑같이 풀어주고 jpa프로젝트에서 헀던 META_INF라는 폴더와 그안에 파일을 통 째로 복붙해서 이번에 만든 거에 넣어줬다.

회원이 여러 주문을 넣고 하나의 주문에는 여러개의 주문 상품이 있을 것임.

com.codingbox.jpaitem.domain패키지 만듦
그아래에 4개 만듦

메인 메서드 만들어서 자바어플리케이션으로 실행해주면 테이블이 만들어진다. 디비버가서 엔티티관계도 보고 확인하자

여기까지하면 테이블은 만들었고 보면 FK가 안만들어져있다.

1. 연관관계 매핑

  • 현재 방식은 객체 설계를 테이블 설계에 맞춘 방식이다.
  • 참조가 없으므로 ERD도 잘못 그려진다. ERD가 엔티티관계도.
    Entity Relationship Diagram : DB설계도

1-1. 연관관계 매핑 기초

  • 객체와 테이블 연관관계의 차이를 이해
  • 객체의 참조와 테이블의 외래 키를 매핑
  • 용어(이 파트에서 알고가야할 중요한 용어)
    방향(Direction) : 단방향, 양방향
    다중성(Multiplicity) : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)
    연관관계 주인(Owner) : 객체 양방향 연관관계는 관리 주인이 필요하다.

1-2. 객체와 테이블 차이점

  • 테이블은 객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력관계를 만들 수 없다.
  • 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
  • 객체는 참조를 사용해서 연관된 객체를 찾는다.
  • 테이블과 객체 사이에는 이런 큰 간격이 존재한다.

1-3. 단방향 연관관계

  • Member에서 Team쪽으로 즉,
    Member가 자식테이블이고, Team이 부모 테이블이되어야한다.
    이거 많이 헷갈리는데 FK가 걸리는 칼럼이 다른 테이블의 id값을 참조한다는 것을 생각하자.

1-4. 양방향 연관관계와 연관관계의 주인

DB에선 팀에서 멤버를 갖는다거나 반대로 멤버에서 팀을 조인하거나 할 수 있다.
이걸 객체에서도 하고싶다!

2. 객체와 테이블이 관계를 맺는 차이

2-1. 테이블 연관관계 = 1개

테이블입장 즉 DB입장에서는 1개이다. FK하나를 가지고말이다.

  • 회원 <-> 팀의 연관관계는 1개이고 양방향 접근이 가능하다.
  • Member 테이블 입장에서 Team 테이블 조인이 가능하다.
  • Team 테이블 입장에서 Member 테이블 조인이 가능하다.

2-2. 객체 연관관계 = 2개

  • 회원-> 팀 연관관계 1개(단방향)
  • 팀 -> 회원 연관관계 1개(단방향)
  • 사실은 단방향 연관관계가 2개 있는 것이다.
  • 억지로 양방향이라고 말하는 것이다.

2-3. 딜레마가 온다.

  • 둘 중 하나로 외래키를 관리해야 한다.
  • Member 에서 Team으로 가는 team 참조 값과, Team에서 Member로 가는 members참조 값이 있다.
    Member에서 Team값이 수정됐을 때 MEMBER Table의 TEAM_ID가 수정이 되야하는지?
    Team에 있는 members를 수정 했을 때 Member에 있는 TEAM_ID가 수정되야하는지?
    둘 중에 무엇을 봐야하는지?
    DB입장에서는 MEMBER테이블에 있는 TEAM_ID만 update가 되면 된다.
    => 룰(주인)이 생긴다.

2-4. 연관관계의 주인(owner)

  • 양방향 매핑에서의 규칙
  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
  • 연관관계의 주인만이 외래 키를 관리(등록, 수정)
  • 주인이 아닌 쪽은 읽기만 가능하도록 할것이다(readonly)
  • mappedBy 속성
    주인은 mappedBy 속성이 사용되지 않는다.
    -> mappedBy : 내가 누군가에 의해서 mapping이 되었다라는 뜻.

2-5. 누구를 주인으로? -> 답이 있다.

  • 외래키가 있는 곳을 주인으로 정해야한다.
  • Member.team이 연관관계의 주인

실선과 점선이 둘다 있는 것이 양방향 연관관계를 의미한다.
주인인곳에서 아닌쪽 -> 실선
주인아닌곳 에서 주인인곳 -> 점선

---------------점심

3. 양방향 연관관계 주의사항

  • 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정해야한다.

  • 근데 항상 이렇게 2번하기 깜빡할 수 있으니까 연관관계 편의 메서드를 생성해 줄것이다.

  • 외부에서 처리되도록 하는 메서드

  • 롬복에서는 게터, 세터, toString등 알아서 만들어 준적이 있다.
    Member 안에 있는 toString안에는 team의 toString() 을 호출하고 team 의toString()은 Member 안에 있는 toString()을 호출하게되면서 무한루프가 된다.

  • 양방향 매핑시에 무한 루프를 조심해야한다(예 : toString(), lombok, ...)

4. 양방향 매핑 정리

  • 단방향 매핑만으로 이미 연관관계 매핑은 완료가 됐다. 양방향 매핑은 반대 방향으로 조회기능이 추가된 것 뿐이다
  • 양방향 사용이유 : JPQL에서 역방햑으로 탐색할 일이 많음
  • 단방향 매핑을 하고 양방할 때핑은 필요할 때 추가해도됨
  • 양방향은 테이블에 영향을 주지 않음
  • 결론 : 객체 입장에서 양방향 매핑은 이득이 별로 되지 않는다.
    필수가 아니다. 따라서 필요시에 그때 생성해도 늦지 않다. (옵션)

5. 연관관계 주인을 정하는 기준

비즈니스 로직을 기준으로 연관관계의 주인을 선택하면 안된다.
연관관계의 주인은 외래키의 기준으로 정해야한다.
오늘거 아닌쪽에 MappedBy를 검색해야한다.

오늘꺼 대로하면 무한스택플로우 에러가 난다
팀에서는 멤버를 호출하고 투스트링으로
멤버에서는 팀을 호출하는 투스트링이있어서 서로 부르니까 무한이다
하나만 주석처리하면 된다.

---day11 시작

  • 이대로 FK를 만들어서 테이블을 만들어보자.

Order와 Member관계만 먼저보자
Order의 member : Member가 Member테이블의 id를 참조하고있으므로 Member테이블이 FK를 가지녀 Owner가 되고 Member테이블이 mappedBy가 된다.
추가로 어감이 좋은 Owner가 @ManyToOne이 되며 이거만 걸면 단방향 매핑이된다.
양방향 매핑을 위해 어감이 안좋은 @OneToMany는 mappedBy의 Member 테이블에 추가를 하면 된다.
이거 중요한 거니까 코드를 추가한다.

  • Order.java
//패키지, 임포트 부분 생략했다.

//@Entity
@Getter @Setter
@Table(name="orders")
public class Order {
//Order라는 것이 DB마다 예약어로 걸려있는 경우가 있으니 이름을 바꾸자
	
	@Id
	@GeneratedValue
	@Column(name="ORDER_ID")
	private Long id;
	
//	@Column(name="MEMBER_ID")	//Member.java에서의 @Id칼럼이름과 동일하게해야 한다.
//	private Long memberId;
	
	@ManyToOne
	@JoinColumn(name="MEMBER_ID")
	private Member member;
	
	private LocalDateTime orderDate;
	private String status;
	
}
  • 물론 Order.java는 OrderItem.java 와도 매핑을 위해 추가로 작업을 했지만 Member.java와 Order.java의 관계만 나타내었다.

나머지 2개추가로 매핑하는 것도 위와 같게 하면 된다.

0개의 댓글