1.Album, Book, Movie 클래스 세팅

 

실습

 

설명

-Item Package로 옮긴 Album,Book,MovieItem클래스로부터 extends를 사용해

 상속받게 한다.

-@Entiyty @Getter @Setter 세팅

 

 

2.ItemAlbum, Book, Movie클래스 상속관계매핑 세팅

실습

a. 싱글테이블전략사용

-상속관계전략을 지정해주어야 한다.(중요!!)

-전략을 부분 클래스에 잡아주어야 하고, 싱글테이블전략을 사용한다.

 

*여기에서는 싱글테이블 전략을 사용

@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 설정을 한다.

 

*@inheritance 타입에 전략 종류 3가지

a. (strategy = inheritanceType.Joined) - 가장 정교화된 스타일

b. (strategy = InheritanceType.TABLE_PER_CLASS)

- 상속받는 클래스를 각각 테이블화 하는 전략

c. (strategy = InheritanceType.SINGLE_TABLE) - 한테이블에 전부 넣는전략

 

#InheritanceType strategy 자세히 보는 방법

(strategy = InheritanceType)에서 Inheritance 우클릭해서

Find Usage->EnumInheritance Type 클릭

 

 

b.@DiscriminatorColumn(name= "dtype")

실습

설명

-ITEM: 앨범, 도서, 화 타입을 통합해서 하나의 테이블로 만들었다.

 dtype 컬럼으로 타입을 구분한다. 컬럼사용을 통해 저장 되어 있는 자식테이블을 구분할 수 있다.

-기본값은 dtype이다.

 

c.@DiscriminatorValue("B") -> Album, Music에도 동일하게 "A", "M"로 세팅

실습

설명

-싱글테이블일 때 book컬럼을 저장할 때 구분할 수 있는 무언가가 DB입장에서 필요하다.

 이 때 넣는 값이다.

-이때 book클래스에서 클래스에 @DiscriminatorValue("B") 로 세팅해준다.

 B값으로 안하고 기본값으로 두면 Book으로 값이 들어간다.

 

 

2. OrderItemItem 연관관계 설정

실습

 

설명

OrderItem ->private Item item 어노테이션 세팅

-@ManyToOne : 주문상품과 상품의 관계, 다대 1관계를 설정해주는 어노테이션

-@JoinColumn(name = "item_id")

*@JoinColumn 어노테이션은 외래 키를 매핑 할 때 사용

*name 속성에는 매핑 할 외래키(연관관계주인) 이름지정

-item_id = foregien key(외래키)

-상품테이블에서 상품에 대한 정보를 매핑

 

-다대일 단방향 관계다

엔티티분석

ORDER

-id

-member : Member

-orderitems : List

-delivery : Delivery

-orderDate : Date

-status : OrderStatus

 

Orderitem

-id

-item : Item

-order : Order

-orderPrice

-count

 

Delivery

-id

-order : Order

-address : Address

-status : DeliveryStatus

 

 

테이블 분석

ORDERS

-MEMBER_ID (FK)

-DELIVERY_ID (FK)

-ORDERDATE

-STATUS

 

ORDER_ITEM

-ORDER_ID(FK)

-ITEM_ID(FK)

-ORDERPRICE

-COUNT

 

DELIVERY

-DELIVERY_ID

-STATUS

-CITY

-STREET

-ZIPCODE

 

 

1. 주문엔티티 추가 개발

 

실습

a. Order클래스에서 

-private List<OrderItem> orderItems = new ArrayList<>();  (OrderItem클래스 생성)

-prviate Delivery delivery; (Delivery 클래스 생성)

-private LocalDateTime orderDate; (주문시간)

*자바8이전엔은 private Date date을 만들어주고, Dateimport 해야했으며,

 날짜관련 어노테이션 매핑을 해주었어야 했다.

 자바8에서는 LocalDateTime를 사용하면 hibernate가 자동으로 위의 행위들을 대신해준다.

-Private OrderStatus status; (@Enumerated(EnumType.STRING)어노테이션 설정해줄 것!)

*(OrderStatus 클래스생성 -> 이것으로 주문상태 Order, Cancel를 관리한다.)

 

OrderStatus클래스 생성

실습

 

b. orderItem 클래스 개발

실습

@ManyToOne@JoinColumn 어노테이션 사용에 대한 설명

orderorderItem 엔티티분석 (양방향연관관계)

-하나의 order과 여러개의 orderItem을 가질 수 있고

 orderItem은 하나의 order만 가질 수 있다.

 매핑에도 order클래스에도 orderitems클래스에도 order가 있다.

 

order과 orderItem 테이블분석

-orderItem( )foreign key가 들어간다.

 order_id가 들어간다. 하나의 주문에 여러개의 orderItem이 들어가기 때문에

-orderItem에서 order가 연관관계의 주인이 된다.

 orderItem에 이어 order측 세팅

 

@OneToMany(mappedBy = "order") -> Order클래스에서 확인

Private List<OrderItem> orderItems = new Arraylist<>();

-order에 의해서 맵핑이 된다는 의미

-@OneToMany : 회원과 주문의 관계, 1대 다 관계를 설정해주는 어노테이션

-@OneToMany (mapped by = "order")

*foreign key가 있는 OrderItem클래스에 있는 order가 연관관계의 주인이다.

*mapped by - orderItem 테이블에 있는 order필드에 의해 맵핑된 거울일 뿐이야라는 뜻

 

 

d.OrderItemprivate Item item과 연동되는 Item클래스 세팅

설명

public abstract class (추상클래스로 만든다. 구현체를 가지고 만들 것이기 때문에)

 

e.Item엔티티분석, 실습 및 Item package 생성 (위의 실습사진 참고)

ITEM 엔티티분석

-id

-name

-price: int

-stockQuantity

-categories : List

 

ITEM 테이블분석

ITEM_ID

-NAME

-PRICE

-STOCKQUANTITY

-DTYPE

-ARTIST

-ETC

-AUTHOR

-ISBN

-DIRECTOR

-ACTOR

 

-stockQuantity 매핑을 해주어야 하고, 밑에 Album, Book, Movie와 상속관계이다.

* 상속관계공부 필요

* private - 속성

* name, price, stockQuantity - 공통속성

 -상속할 Album, Book, Movie은 일일이 만들어주어야 하는 것들이다.

 

Item package 생성

설명

-Item package를 만들어 Item,Album, Book, Movie클래스에 옮긴다.

주문(order)엔티티클래스파일에서

실습

 

order_id

-DB컬럼의 id이름을 테이블명으로 가져와 테이블명_id형태로 설정해준다.

DBA포지션 엔지니어가 이러한 형태로 설정해주는 것을 원한다.

 

참고

엔티티의 식별자는 id를 사용하고 PK 컬럼명은 member_id를 사용했다. 엔티티는 타입(여기서는 Member)이 있으므로 id 필드만으로 쉽게 구분할 수 있다. 테이블은 타입이 없으므로 구분이 어렵다. 그리고 테이블은 관례상 테이블명 + id를 많이 사용한다. 참고로 객체에서 id 대신에 memberId를 사용해도 된다. 중요한 것은 일관성이다.

 

-@ManyToOne : 주문과 회원의 관계, 다대 1관계를 설정해주는 어노테이션

-@JoinColumn(name = "member_id")

*@JoinColumn 어노테이션은 외래 키를 매핑 할 때 사용

*name 속성에는 매핑 할 외래키(연관관계주인) 이름지정

-member_id = foregien key(외래키)

-주문회원테이블에서 주문회원에 대한 정보를 매핑

 

 

 

회원엔티티클래스(RealMember)에서

어노테이션 설정

-@OneToMany : 회원과 주문의 관계, 1대 다 관계를 설정해주는 어노테이션

-@OneToMany (mapped by = "member")

*foreign key가 있는 order클래스에 있는 member가 연관관계의 주인이다.

*mapped by - order 테이블에 있는 member필드에 의해 맵핑된 거울일 뿐이야라는 뜻

*여기에 무엇을 넣는다고 해서 order에 있는 member필드의 foreign key 값이 변경되지

 않는다.

*order엔티티클래스에 있는 order테이블에 있는 member필드 값을 변경하면

 member_idforeign key 값이 변경된다.

 

 

연관관계의 주인설정이 필요한 이유

연관관계 맵핑 분석을 다시 확인해보자

회원과 주문

-회원도 오더로 갈 수 있고, 오더도 회원으로 갈 수 있도록 설계 했다.(양방향 연관관계)

-일대다, 다대일의 양방향 관계다. 따라서 연관관계의 주인을 정해야 한다.

 관계형데이터베이스에서는 1대 다의 관계에서는 다에 무조건 외래키가 있게 된다.

 외래 키가 있는 주문을 연관관계의 주인으로 정하는 것이 좋다.

 

이유

-주문클래스에서 멤버값을 바꾸거나, 멤버클래스에서 오더값을 바꿀 수도 있기 때문에

 JPA는 혼란스러울 수 있다.

-회원엔티티로 본다면 Order도 멤버정보를 가지고 있고, Member도 주문정보를 가지고 있

 다. 데이터베이스에서 MemberOrder테이블에서 볼 때에 foreign keyOrder테이블에

 한 개 밖에 없는 상태이다.

-추후 일어날 수 있는 문제라고 한다면, 회원과 주문테이블 관계를 바꾸고 싶을 때 foreign

 key를 변경해야 하는 상황에 처하게 된다.

-Member테이블에도 orders라는 컬렉션 필드가 있는거고, Order테이블에도 member라는

 필드가 있어 JPA에서는 둘다 정보를 확인해서 값을 바꾸어야 하나라는 혼란에 빠진다.

 즉, 어디에 값이 바뀌었을 때 foreign key를 바꾸어야 하는지에 대한 혼란을 겪게 된다.

-극단적으로 Order엔티티에서는 member 값을 세팅했는데, Member엔티티에서 order 값을

 세팅 안한다던가, Member엔티티에서는 order값을 넣었는데, Order엔티티에서는 member

 값을 안넣었다던가 하는 경우가 생기면, JPA는 둘중에 무엇을 믿고 order테이블의 foreign

 key 값을 업데이트를 해야 하지?라고 혼란을 겪는다.

 

여기서 foreign keyupdate하게 하기 위해서 JPA에서 둘중에 하나를 선택하라고 약속을 했다. 엔티티에서의 객체는 변경 포인트가 두군데이지만, 테이블은 foreign key하나만 변경하면 되기 때문에, 쉽게 맞추기 위해 규칙을 정했다.

둘중에 하나를 주인이라는 개념으로 잡으면 되는데 이것이 연관관계의 주인이다.

Member엔티티에서 ordersOrder엔티티에서나 member중에 값이 바뀌었을 때에 foreign key를 바꿀 거야 라는 것을 결정을 하는 것이 연관관계의 주인이다.

 

그렇다면 연관관계의 주인은 누구로 하는가?

-foreign key가 가까운 테이블(Order)을 확인하고 Member_id를 연관관계주인이 있는 곳으

 로 맵핑을 하면 된다.

-Order엔티티의 member가 가까우니 여기를 연관관계주인으로 정한다.

-이렇게 하지 않으면 member의 무언가를 바꾸었는데, Order테이블에 무언가/foregin키가

 업데이트 되어버려서 있는 의도치 않은 일이 일어난다. 성능이슈가 생길 수도 있다.

 Member정보를 변경했는데, orders의 값이 바뀌지하고 헷갈리게 되어버린다.

-foreign key가 있는 Order테이블에 있는 member를 바꾸니까 order테이블에 있는 컬럼이

 바뀌는구나 하고 이해하기도 관리하기도 쉬워진다. 이렇게 규칙을 정하지 않으면 Member

 보를 변경했는데, orders의 값이 바뀌지하고 헷갈리게 된다.

들어가기에 앞서

-예제에서 쉽게 설명하기 위해서 엔티티클래스에 setter getter를 모두 열어두어

 단순하게 설계를 할 것이다.

-실무에서는 getter는 열고, setter는 꼭 필요할 때에만 사용하는 것을 추천한다.

 

1. 회원엔티티개발

 

실습

회원엔티티클래스 생성 및 작성

설명

회원엔티티개발

a. jpabook.jpashopPackagedomain이라고 만든다.

-여기에 핵심 엔티티들을 설치 할 것이다.

 

b. 회원엔티티 작성

-List, ArrayList import class를 해줌

 

c. Address, Order 클래스 파일 생성

 

c. 회원테이블 이름 매핑

-@Id, @generatedValue, @Columns 어노테이션 세팅

 

2.주소값 타입 개발

실습

주소값타입개발

설명

a. address주소 클래스에서 코드작성

@Embeddable 어노테이션 사용

-address 주소가 어딘가에 내장될 수 있게 하기 위해 사용

@Getter 어노테이션을 열어두기

 

b.회원엔티티(RealMember)클래스파일에서 내장타입관련 어노테이션 세팅

-Address변수에 내장타입을 포함했다라는 @Embedded 어노테이션으로 매핑을 해주었다.

-Address변수에 @Embedded 하나만 있어도 되지만,  대개 두가지 어노테이션을 많이 사용한다.

 

3. 주문(order)엔티티클래스파일에서

실습

주문엔티티클래스 생성 및 작성(주문과 회원관계 연관관계매핑)

설명

a.주문엔티티클래스파일에서

-@Entity, @Table 이름 설정을 했다.

-@Table(name = "orders")라고 해주지 않으면

  public class Order에서 Order의 관례로 이름이 Order가 되어 버리기 때문에 이름 설정을 해주어야 한다.

 

b.order_id

-DB컬럼의 id이름을 테이블명으로 가져와 테이블명_id형태로 설정해준다.

 DBA포지션 엔지니어가 이러한 형태로 설정해주는 것을 원한다.

 

참고

엔티티의 식별자는 id를 사용하고 PK 컬럼명은 member_id를 사용했다. 엔티티는 타입(여기서는 Member)이 있으므로 id 필드만으로 쉽게 구분할 수 있다. 테이블은 타입이 없으므로 구분이 어렵다.

그리고 테이블은 관례상 테이블명 + id를 많이 사용한다.

참고로 객체에서 id 대신에 memberId를 사용해도 된다. 중요한 것은 일관성이다.

 

c.@ManyToOne

-주문과 회원의 관계, 다대 1관계를 설정해주는 어노테이션

 

d.@JoinColumn(name = "member_id")

-@JoinColumn 어노테이션은 외래 키를 매핑 할 때 사용

 

e.name 속성에는 매핑 할 외래키(연관관계주인) 이름지정

-member_id = foregien key(외래키)

-주문회원테이블에서 주문회원에 대한 정보를 매핑

 

 

4. 회원엔티티클래스(RealMember)에서

실습

회원엔티티 연관관계 매핑

 

a.어노테이션 설정

@OneToMany

-회원과 주문의 관계, 1대 다 관계를 설정해주는 어노테이션

 

@OneToMany (mapped by = "member")

-foreign key가 있는 order클래스에 있는 member가 연관관계의 주인이다.

-mapped by - order 테이블에 있는 member필드에 의해 맵핑된 거울일 뿐이야라는 뜻

-여기에 무엇을 넣는다고 해서 order에 있는 member필드의 foreign key 값이 변경되지

 않는다.

-order엔티티클래스에 있는 order테이블에 있는 member필드 값을 변경하면

 member_idforeign key 값이 변경된다.

 

어노테이션 설명 참고

https://docs.oracle.com/javaee/6/api/index.html

어노테이션이 궁금하다면 java.persistence -> annotation type을 클릭하면 어노테이션 설명을 볼 수 있다.

 

+ Recent posts