본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
JPA

실전 예제 1 - 요구사항 분석과 기본 매핑(2)

by 방구석 대학생 2020. 9. 22.

"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."

www.inflearn.com/course/ORM-JPA-Basic#

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그

www.inflearn.com

 

 

- 도메인 클래스를 작성시 주의 할 점

: 강의를 통해 Member, Order, OrderItem, Item 도메인 클래스를 생성하였다.

이 과정에서 주의 해야 할 점이 생겼는데 바로 도메인 클래스간 객체의 데이터를 참조해야 할 때였다.

 

Member 클래스와 Order 클래스 간에 데이터를 참조해야 하는 경우가 생겼는데 두 클래스의 코드는 아래와 같았다.

- Member 클래스

@Entity
public class Member {

	@Id @GeneratedValue
	@Column(name = "MEMBER_ID")
	private Long id;
	private String name;
	private String city;
	private String street;
	private String zipcode;
    
    // Getter & Setter
}

 

- Order 클래스

@Entity
@Table(name = "ORDERS") // 테이블 설계에서 작성된 대로 테이블 명을 지정한다.
public class Order {

	@Id @GeneratedValue
	@Column(name = "ORDER_ID")
	private Long id;

	@Column(name = "MEMBER_ID")
	private Long memberId;

	private LocalDateTime orderDate;

	@Enumerated(EnumType.STRING)
	private OrderStatus status;
    
    // Getter & Setter
}

 

그런데 위와 같이 도메인 클래스를 작성하면 JPA 에서 주문 데이터를 통해 멤버 데이터를 검색하는데 있어 문제가 발생한다.

우선 JPA 를 통해 주문 번호 객체에서 멤버 객체 데이터를 검색하는 코드를 살펴보자.

Order order = em.find(Order.class, 1L);
Long memberId = order.getMemberId();

Member member = em.find(Member.class, memberId);

위의 코드를 보면 특정 주문 번호 데이터를 검색한 다음, 해당 주문을 한 멤버의 id 값이 무엇인지 알아 낸 후, 해당 id 값을 통해 멤버 객체 데이터를 검색하고 있다.

 

위의 방식은 다분히 객체지향 스럽지 않은 방식이다.(객체를 관계형 DB에 맞춰서 설계할 경우의 방식에 가깝다, 즉 데이터 중심의 설계방식이다.)

 

여기서 주문 데이터를 이용해 멤버 데이터를 가져오는데 있어, 위와 같이 주문 번호 자체를 이용하여 해당 멤버를 찾는것보다, 아예 Order 클래스에서 Member 측의 데이터를 곧장 가져올 수 있게끔 만들면 훨씬 간편하고 객체지향적으로

프로그램을 코딩할 수 있다. 

 

그럼 여기서 Member 측의 데이터를 가져올 수 있게끔 Order 클래스에 Member 클래스 객체를 선언해두자.

@Entity
@Table(name = "ORDERS") // 테이블 설계에서 작성된 대로 테이블 명을 지정한다.
public class Order {

	@Id @GeneratedValue
	@Column(name = "ORDER_ID")
	private Long id;

	private Member member; // Long 형의 memberId 가 아닌 Member 클래스의 객체를 선언한다.
    // Getter, Setter 또한 함께 만들어준다.

	private LocalDateTime orderDate;

	@Enumerated(EnumType.STRING)
	private OrderStatus status;
    
    // Getter & Setter
}

 

Order 클래스를 위와 같이 작성함 으로서 JPA 에서는 주문 번호를 통해 멤버 데이터를 검색하여 이용할 때 다음과 같은 방식으로 코드를 작성할 수 있다.

Order order = em.find(Order.class, 1L);
Member findMember = order.getMember(); 
// 주문 번호를 통해 찾은 주문 데이터를 통해 곧장 Member 데이터를 가져온다.

 

위와 같이 Order 클래스에서 Member 객체를 얻어올 수 있게끔 객체를 선언해두면 간편하게 Member 데이터를 찾아올 수 있다.

- Member 객체를 선언해두지 않았을 경우 과정

1. 주문 데이터 검색 -> 2. 주문에 해당하는 멤버 번호 검색 -> 3. 멤버 검색

- Member 객체를 선언해 두었을 경우 과정

1. 주문 데이터 검색 -> 2. 주문 데이터에 해당하는 멤버 검색

 

즉, 멤버 번호를 찾는 과정을 거칠 필요 없이 더 빠르게 멤버 정보를 찾아올 수 있게 된다.

 

그렇다면 처음 작성했던 것처럼 데이터 중심으로 설계를 하게 되면 어떤 문제점이 발생하게 될 까?

- 참조 값을 가져오는 것이 아니라 테이블의 외래키를 객체에 그대로 가져오게 된다.

- 그에 따라 객체 그래프 탐색이 불가능해 진다.

- 참조가 없으므로 강의 자료에 그려진 UML 또한 잘못되어 있다.

(UML 은 프로그램 설계를 표현하기 위해 사용하는, 주로 그림으로 된 표기법을 말한다. - 대표 이미지의 테이블 설계 그림과 같은 것)

(객체 지향 언어와 밀접한 관련이 있기에 객체지향 모델링 언어라고도 불린다.)

 

위와 같은 객체 지향 중심 설계를 잘하기 위해 다음번엔 연관관계 매핑에 대한 강의를 듣고 블로그에 글을 작성해보자.

'JPA' 카테고리의 다른 글

연관관계 매핑 기초 - 2  (0) 2020.09.28
연관관계 매핑 기초 - 1  (0) 2020.09.27
실전 예제 1 - 요구사항 분석과 기본 매핑(1)  (0) 2020.09.22
기본 키 매핑 - 3  (0) 2020.09.21
기본 키 매핑 - 2  (0) 2020.09.21