본문 바로가기
Study/spring

자바 ORM 표준 JPA 프로그래밍(6) - 엔티티 매핑 실습

by 유경호 2020. 12. 27.
반응형

요구사항 분석

  • 회원은 상품을 주문할 수 있다.
  • 주문 시 여러 종류의 상품을 선택할 수 있다

 

기능 목록

  • 회원 기능
  • 회원등록
  • 회원조회
  • 상품 기능
  • 상품등록
  • 상품수정
  • 상품조회
  • 주문 기능
  • 상품주문
  • 주문내역조회
  • 주문취소

 

도메인 모델 분석

  • 회원과 주문의 관계: 회원은 여러 번 주문할 수 있다. (1:n)
  • 주문과 상품의 관계: 주문할 때 여러 상품을 선택할 수 있다. 반대로 같은 상품도 여러 번 주문될 수 있다. 주문상품 이라는 모델을 만들어서 다대다 관계를 1:n, m:1 관계로 풀어냄

 

테이블 설계

엔티티 설계

엔티티 매핑 작성

Member

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Entity
@Table(name = "member")
@Getter @Setter
public class Member {
 
    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;
 
    private String name;
 
    private String city;
 
    private String street;
 
    private String zipcode;
}
cs

 

Orders

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Entity
@Table(name = "orders")
@Getter @Setter
public class Order {
 
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "order_id")
    private Long id;
 
    @Column(name = "member_id")
    private Long memberId;
 
    @Column(name = "order_date")
    private LocalDateTime orderDate;
 
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
}
cs

 

Item

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Entity
@Table(name = "item")
@Getter @Setter
public class Item {
 
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "item_id")
    private Long id;
 
    private String name;
 
    private int price;
 
    @Column(name = "stock_quantity")
    private int stockQuantity;
}
cs

 

OrderItem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entity
@Table(name = "order_item")
@Getter @Setter
public class OrderItem {
 
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "order_item_id")
    private Long id;
 
    @Column(name = "order_id")
    private Long orderId;
 
    @Column(name = "item_id")
    private Long itemId;
 
    private int orderprice;
 
    private int count;
}
cs

 

DDL 생성 코드

Hibernate: 

    create table Item (
       item_id bigint generated by default as identity,
        name varchar(255),
        price integer not null,
        stock_quantity integer,
        primary key (item_id)
    )
Hibernate: 

    create table Member (
       member_id bigint generated by default as identity,
        city varchar(255),
        name varchar(255),
        street varchar(255),
        zipcode varchar(255),
        primary key (member_id)
    )
Hibernate: 

    create table ORDER_ITEM (
       ORDER_ITEM_ID bigint generated by default as identity,
        count integer not null,
        ITEM_ID bigint,
        ORDER_ID bigint,
        orderprice integer not null,
        primary key (ORDER_ITEM_ID)
    )
Hibernate: 

    create table ORDERS (
       ORDER_ID bigint generated by default as identity,
        MEMBER_ID bigint,
        order_date timestamp,
        status varchar(255),
        primary key (ORDER_ID)
    )

데이터 중심 설계의 문제점

  • 현재 방식은 연관관계 매핑을 적용하지 않고 객체 설계를 테이블 설계에 맞춘 방식
  • 테이블의 외래키를 객체에 그대로 가져옴
  • 객체 그래프 탐색이 불가능
  • 참조가 없으므로 UML도 잘못됨

 

위 처럼 데이터 중심 설계가 되어 외래 키만 가지고 있으면 연관된 엔티티를 찾을 때 외래 키로 데이터베이스를 다시 조회해야 한다.

1
2
3
Order order = em.find(Order.class, orderId);
// 외래 키로 다시 조회
Member memeber = em.find(Member.class, order.getMemeberId());
cs

 

객체는 참조를 사용해서 연관관계를 조회할 수 있다. 따라서 아래와 같이 사용할 수 있어야 객체지향적인 방법이다.

1
2
Order order = em.find(Order.class, orderId);
Member memeber = order.getMember(); // 참조 사용
cs

 

JPA가 제공하는 연관관계 매핑을 적용하면 위의 문제를 해결할 수 있다.

반응형