1.Category 엔티티분석 및 카테고리 테이블분석

 

Category 엔티티

-id

-name

-items: List (다대 다 관계)

-parent: Category

-child: List

-상품과 다대다 관계를 맺는다. parent, child로 부모, 자식 카테고리를 연결한 다.

*계층 구조를 이렇게 매핑할 수 있다를 보여주기 위해 이렇게 설정 했다.

*자기자신을 셀프로 계층구조형태로 매핑을 하진 않았을 것 같아 이렇게 설정했다.

 

카테고리 테이블 분석

CATEGORY_ID

-PARENT_ID (FK)

-NAME

 

설명

카테고리와 상품 테이블 분석

-@ManyToMany를 사용해서 매핑한다.

(실무에서 @ManyToMany는 사용하지 말자. 여기서는 다대다 관계를 예제로 보여주기 위해 추가했을 뿐이다)

 

 

2.(Category_Item)중간테이블 및 카테고리와 상품 연관관계 맵핑

 

CATEGORY_ITEM

-CATEGORY_ID (FK)

-ITEM_ID (FK)

 

카테고리 엔티티

-id

-name

-items: List

-parent: Category

-child: List

 

아이템 엔티티

-id

-name

-price : int

-stockQuantity

-categories: List

 

a.카테고리클래스에서 상품과 맵핑

설명

@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id),
inverseJoinColumns = @JoinColumn(name = "item_id"))

 

@JoinTable

-객체는 컬렉션이 있어 다대 다관계가 가능하지만

 관계형 DB는 컬렉션관계를 양측에 가질 수 있는 것이 아니기 때문에 1대 다, 다대 1 관계의

 중간테이블을 이용한다.

 

@JoinTable어노테이션

-중간테이블에 있는 외래 키를 매핑 할 때 먼저 사용

 

joinColumns = @joinColumn(name="category_id)

-중간테이블에 있는 category_id 외래키 매핑

 

inverseJoinColumns = @JoinColumn(name = "item_id")

-중간테이블에 있는 item_id 외래키 매핑(item과 연관관계 매핑하기 위함)

 

b.Item클래스에서 카테고리와 맵핑

실습

설명

@ManyToMany(mappedBy ="items")

private List(Category> categories = new ArrayList<>();

 

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

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

 

주의

실무에서 @ManyToMany는 사용하지 말자.

-실무에서는 다대 다관계로 연관관계를 풀어내지 말 것

-이러한 상태의 테이블만 구현이 가능하고, 다른 필드를 추가하는 것이 불가하다.

 

 

3. 카테고리 구조

 

카테고리가 계층구조로 내려간다.

위의 부모구조 아래에는 자식구조

 

실습

@ManyToOne
@JoinColumn(name ="parent_id")
private Category parent;

@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();

설명

-자식 카테고리는 여러개 가질 수 있다.

-셀프로 category안에서 이름만 다를 뿐이지 양방향 연관관계 매핑하듯이 해주면 된다.

 

자 이제 작성한대로 데이터베이스 테이블이 제대로 구성이 되었는지 확인해 보자.

그리고 실제 데이터베이스 테이블구성 및 데이터베이스 명령어 작성/실행

 

실습

create table orders (

order_id bigint not null,

order_date timestamp,

status varchar(255),

delivery_id bigint,

member_id bigint,

primary key (order_id)

);

-> 이것으로 실행시키면 원래 작성했던 코드대로 테이블 구성이 된다.

*JPAalter할 때 작성한 foreign키 컬럼을 전부 잡아준다.

 

참고

foreign key를 꼭 걸어야 되요 안 걸어야 되요?

-시스템마다 다르다.

-실시간 트래픽이 중요하고, 정확성보다는 잘 서비스가 되는 유연한 것이 중요하면

 foreign key를 빼고, 인덱스만 잘 잡아주면 된다.

-하지만, 돈과 관련된 중요한 것이라던가, 데이터가 항상 맞아야 하는 시스템이라면

 foreign key를 넣어주면 된다.

주문(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의 값이 바뀌지하고 헷갈리게 된다.

2-1. 도메인모델과 테이블 설계

a.회원, 주문, 상품의 관계

-회원은 여러 상품을 주문할 수 있다. 그리고 한 번 주문할 때 여러 상품을 선택할 수 있기에 주문과 상품은 다대다 관

-하지만 이런 다대다 관계는 관계형 데이터베이스는 물론이고 엔티 티에서도 거의 사용하지 않는다.

-따라서 그림처럼 주문상품이라는 엔티티를 추가해서 다대다 관계를 일대 다, 다대 일 관계로 풀어냈다.

 

상품 분류

-상품은 도서, 음반, 화로 구분되는데 상품이라는 공통 속성을 사용하므로 상속 구조로 표현했 다.

 

b.회원과 주문 관계

-회원은 여러 주문을 할 수 있어서 회원과 주문의 관계는 1대 다의 관계이다.

 

c.회원과 주문, 주문과 상품 관계

-회원이 한번 주문할 때 여러개의 상품을 주문할 수 있다.

-상품도 여러 주문에 담길 수 있으면 다대 다 관계가 된다.

-하지만 이런 다대다 관계는 관계형 데이터베이스는 물론이고 엔티티에서도 거의 사용하지 않는다.

-그래서 1대 다 다 대 1의 관계 관계로 만들기 위해

 그림처럼 주문상품(테이블+주문수량)이라는 엔티티를 추가해서 다대다 관계를 일대 다,

 다대일 관계로 풀어냈다.

 

d.주문과 배송정보

-11 관계

-주문할 때 배송정보를 입력할 수 있도록 해놓음

 

e.상품

-도서, 음반, 영화 로 타입이 나누어짐

 

f.상품과 카테고리

-상품은 카테고리에 매핑이 된다.

-하나의 카테고리에 여러 가지 상품이 들어갈 수도 있고,

 어떤 상품이 카테고리에 복수로 들어갈 수 있기 때문에

 다대 다 관계로 세팅

 

g.데이터베이스의 목적

(참고 블로그 http://kdskor.blogspot.com/2010/10/pk-fk.html)

-효율적이고, 성능면에서 매우 편리하며 신속하게 수많은 데이터들을 보관 및 관리하는 것

-그 중에서도 제일 우선시 되어야 하는 것이 데이터의 무결성이다.

 신속하게 처리한다 하더라도 데이터에 결점이 있다면 데이터는 쓸모가 없을 뿐 아니라,

 데이터의 결점으로 인하여 잘못된 결과를 초래

-데이터 무결성을 보장해주기 위해서 가장 기본적으로 필요한 것이 PKFK

 

h.PK(Primary Key)FK(Foreign Key)

PK

-데이터베이스 생성에서 가장 기본적으로 고려되는 것이 PK

-PK만큼 중요한 것이 FK

-PK는 테이블에서 오직한개만 존재

-PK가 데이터의 유일성을 보장

-테이블에서 PK를 조건으로 조회하여 한 개의 값만 나오거나 값이 나오지 않게 됨

 

FK

-외래 키는 참조하는 테이블에서 1개의 키(속성 또는 속성의 집합)에 해당하고,

 참조하는 측의 관계 변수는 참조되는 측의 테이블의 키를 가리킨다.

-관계형 데이터베이스에서 외래 키(외부 키, Foreign Key)는 한 테이블의 필드(attribute) 중 다른 테이블의 행(row)

 식별할 수 있는 키

 

)아파트테이블 세대테이블의 아파트코드값에

   아파트테이블의 아파트코드에 없는 값이 들어간다면?

   이 때 데이터를 저장 또는 수정시 아파트코드 데이터는 아파트 테이블에 있는 아파트코드

   가 맞는지 확인해야 하는데, 이것이 자동적으로 확인되도록 도와주는 것이 FK이다.

+ Recent posts