코드 그라데이션
실전 예제 1 - 요구사항 분석과 기본 매핑 본문
이것 아마 인프런 <실전 스프링 부트와 JPA 활용 1편> 예제와 동일하거나 최소한 비슷한 듯.
요구사항 분석
- 회원은 상품을 주문할 수 있다.
- 주문 시 여러 종류의 상품을 선택할 수 있다.
기능 목록
회원 기능
- 회원 등록
- 회원 조회
상품 기능
- 상품 등록
- 상품 조회
- 상품 수정
주문 기능
- 상품 주문
- 주문 내역 조회
- 주문 취소
완성된 페이지 모양
도메인 모델 분석
회원과 주문의 관계
- 회원은 여러 번 주문할 수 있다.(일대다)
주문과 상품의 관계
- 주문할 때 여러 상품을 선택할 수 있다.
- 같은 상품도 여러 번 주문될 수 있다.
- '주문상품'이라는 모델을 만들어서 다대다 관계를 일대다, 다대일 관계로 풀어낸다.
테이블 설계
엔티티 설계와 매핑
이제, 기초 코드
Item
@Entity
public class Item {
@Id
@GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
private int stockQuantity;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getStockQuantity() {
return stockQuantity;
}
public void setStockQuantity(int stockQuantity) {
this.stockQuantity = stockQuantity;
}
}
Member
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "MEMBER_ID")
private Long id;
private String name;
private String city;
private String street;
private String zipcode;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
}
Order
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ORDER_ID")
private Long id;
@Column(name = "MEMBER_ID")
private Long memberId;
// private Member member;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getMemberId() {
return memberId;
}
public void setMemberId(Long memberId) {
this.memberId = memberId;
}
public LocalDateTime getOrderDate() {
return orderDate;
}
public void setOrderDate(LocalDateTime orderDate) {
this.orderDate = orderDate;
}
public OrderStatus getStatus() {
return status;
}
public void setStatus(OrderStatus status) {
this.status = status;
}
// public Member getMember() {
// return member;
// }
//
// public void setMember(Member member) {
// this.member = member;
// }
}
OrderItem
@Entity
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@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;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public Long getItemId() {
return itemId;
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
public int getOrderPrice() {
return orderPrice;
}
public void setOrderPrice(int orderPrice) {
this.orderPrice = orderPrice;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
OrderStatus
public enum OrderStatus {
ORDER, CANCEL
}
JpaShopMain
public class JpaShopMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
// Order order = em.find(Order.class, 1L);
// Long memberId = order.getMemberId();
// Member member = em.find(Member.class, memberId);
// Member findMember1 = order.getMember();
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
이걸 실행해보면
따로 정해주지 않으면 컬럼명과 필드명이 동일하게 간다고 생각하면 된다.
Hibernate:
create table Item (
ITEM_ID bigint not null,
name varchar(255),
price integer not null,
stockQuantity integer not null,
primary key (ITEM_ID)
)
01:54:32.744 [main] DEBUG org.hibernate.SQL -
Hibernate:
create table Member (
MEMBER_ID bigint not null,
city varchar(255),
name varchar(255),
street varchar(255),
zipcode varchar(255),
primary key (MEMBER_ID)
)
01:54:32.745 [main] DEBUG org.hibernate.SQL -
Hibernate:
create table OrderItem (
ORDER_ITEM_ID bigint not null,
count integer not null,
ITEM_ID bigint,
ORDER_ID bigint,
orderPrice integer not null,
primary key (ORDER_ITEM_ID)
)
01:54:32.746 [main] DEBUG org.hibernate.SQL -
Hibernate:
create table orders (
ORDER_ID bigint not null,
MEMBER_ID bigint,
orderDate timestamp,
status varchar(255),
primary key (ORDER_ID)
)
메타데이터는 그냥 엔티티 클래스에 그대로 적어라.
이 엔티티만 봐도 개발자가 바로 알 주 있으니까.
인덱스도 웬만하면 적어라.
그래야 개발자들이 JPQL 같은 걸 짤 때 테이블 보고 왓다갔다 하는 등의 번거로움을 줄일 수 있게 됨.
Order를 한 멤버를
사실
@Column(name = "MEMBER_ID")
private Long memberId;
이렇게 찾을 게 아니라.
(이렇게 찾아버리면
try {
Order order = em.find(Order.class, 1L);
Long memberId = order.getMemberId();
Member member = em.find(Member.class, memberId);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
이렇게 매우 성가신 코드가 되므로 객체지향적이라고 보기엔 좀 그렇다...
그래서
private Member member;
이렇게 엔티티를 바로 필드로 받아서
try {
Order order = em.find(Order.class, 1L);
// Long memberId = order.getMemberId();
//
// Member member = em.find(Member.class, memberId);
Member findMember1 = order.getMember();
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
이렇게 바로 받을 수 있다.
728x90
'Spring > JPA 공부' 카테고리의 다른 글
양방향 연관관계와 연관관계의 주인 (0) | 2023.08.19 |
---|---|
단방향 연관관계 (0) | 2023.08.18 |
<보충설명> 기본키 매핑 (0) | 2023.08.16 |
엔티티 매핑 4 - 기본키 매핑 (0) | 2023.08.16 |
엔티티 매핑 3 - 필드와 컬럼 매핑 (0) | 2023.08.15 |
Comments