JPA - 값 타입(1)

DevSeoRex·2022년 11월 27일
0
post-thumbnail
post-custom-banner

값 타입

  • 엔티티 타입은 @Entity로 정의한 객체이다.
  • 값 타입은 int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체를 말한다.
  • 엔티티 타입은 식별자를 통해 지속해서 추적할 수 있다.
  • 값 타입은 식별자가 없고 숫자나 문자같은 속성만 있으므로 추적이 불가능하다.

값 타입 분류

값 타입은 아래와 같이 3가지로 나눌 수 있다.

  • 기본값 타입 - basic value type
    • 자바 기본 타입(예 : int, double)
    • 래퍼 클래스(예 : Integer)
    • String
  • 임베디드 타입(복합 값 타입)
  • 컬렉션 값 타입

기본 값 타입

// 기본 값 타입 예제
@Entity
public class Member {
	
    @Id @GeneratedValue
    private Long id;
    
    private String name;
    private int age;
    ...
}
  • 위의 코드에서는 String, int가 값 타입이다.
  • 값 타입인 name, age 속성은 식별자 값도 없고 생명주기도 회원 엔티티에 의존한다.
  • 값 타입은 공유하면 안된다.

임베디드 타입(복합 값 타입)

  • 새로운 값 타입을 직접 정의해서 사용하는 것을 임베디드 타입이라 한다.
  • 직접 정의한 임베디드 타입도 값 타입에 속한다.
// 임베디드 타입 적용 전 엔티티 예제
@Entity
public class Member {
	
    @Id @GeneratedValue
    private Long id;
    private String name;
    
    // 근무 기간
    @Temporal(TemporalType.Date) Date startDate;
    @Temporal(TemporalType.Date) Date endDate;
    
    // 집 주소 표현
    private String city
    private String street;
    private String zipcode;
    // ...
}

위의 엔티티를 누군가에게 설명한다면 이렇게 설명할 것 같다.

  • 회원 엔티티는 이름, 근무 시작일, 근무 종료일, 주소, 도시, 우편번호를 가진다.

이 엔티티를 아래와 같은 설명처럼 바꿀 수는 없을까?

  • 회원 엔티티는 이름, 근무기간, 집 주소를 가진다.

회원 엔티티에 속한 모든 데이터를 그대로 가지고 있는 것은 객체지향적이지 못하다.
따라서 임베디드 타입을 사용해 근무기간, 주소와 같은 타입을 만들어 사용하게 된다.

// 임베디드 값 타입 적용 예제 - 엔티티
@Entity
public class Member {

	@Id @GeneratedValue
    private Long id;
    private String name;
    
    @Embedded Period workPeriod; 		// 근무기간
    @Embedded Address homeAddress;		// 집 주소
    
}

// 임베디드 타입 정의 예제 - 기간 임베디드 타입
@Embedded
public class Period {
	
    @Temporal(TemporalType.Date) Date startDate;
    @Temporal(TemporalType.Date) Date endDate;
    
   //...
   
   public boolean isWork(Date date) {
   		//... 값 타입을 위한 메서드를 정의할 수 있다.
   }
}

// 임베디드 타입 정의 예제 - 주소 임베디드 타입
@Embedded
public class Address {
	
    @Column(name="city") // 매핑할 컬럼 정의 가능
    private String city;
    private String street;
    private String zipcode;
    
    //...
> }

  • 회원 엔티티가 더욱 의미 있고 응집력 있게 변했다.
  • startDate & endDate를 합해서 Period(기간)을 만들었다.
  • city, street, zipcode를 합해서 Address(주소)를 만들었다.
  • 임베디드 타입을 사용하려면 2가지 애너테이션이 필요하다.
    • @Embeddable : 값 타입을 정의하는 곳에 표시
    • @Embedded : 값 타입을 사용하는 곳에 표시

💡 임베디드 타입은 기본 생성자가 필수다.

임베디드 타입과 테이블 매핑

  • 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.
  • 임베디드 타입은 엔티티의 값일 뿐이므로, 값이 속한 엔티티의 테이블에 매핑한다.

임베비드 타입과 연관관계

  • 임베디드 타입은 값 타입을 포함하거나 엔티티를 참조할 수 있다.
// 임베디드 타입과 연관관계 예제
@Entity
public class Member {
	
    @Embedded Address address; 			// 임베디드 타입 포함
    @Embedded PhoneNumber phoneNumber;	// 임베디드 타입 포함
    
}

@Embeddable
public class Address {
	String street;
    String city;
    String state;
    @Embedded Zipcode zipcode; // 임베디드 타입 포함
}

@Embaddable
public class Zipcode {
	String zip;
    String plusFor;
}

@Embaddable
public class PhoneNumber {
	String areaCode;
    String localNumber;
    @ManyToOne PhoneServiceProvider provider; // 엔티티 참조
    ...
}

@Entity
public class PhoneServiceProvider {
	@Id String name;
    ...
}
  • 위의 예제를 보면 값 타입인 Address가 값 타입인 Zipcode를 포함하고, 값 타입인 PhoneNumber가 엔티티 타입인 PhoneServiceProvider를 참조한다.

출처 : 자바 ORM JPA 프로그래밍 기초편(인프런, 김영한) & 자바 ORM JPA 프로그래밍(에이콘, 김영한)

post-custom-banner

0개의 댓글