[인프런 김영한] JPA - 임베디드 타입(복합 값 타입)

2021. 2. 12. 16:08프로그래밍 언어/Spring Framework

[인프런 김영한] JPA - 임베디드 타입(복합 값 타입)


해당 글은 인프런 김영한강사님의 영상을 보고 정리한 글입니다.

Spring Boot, Spring Data JPA를 사용해 실습하였습니다.

김영한 인프런 : www.inflearn.com/users/@yh

 

인프런 - 김영한의 강의들을 만나보세요.

우아한형제들 개발 팀장 (전: 카카오, SK플래닛) 저서: 자바 ORM 표준 JPA 프로그래밍

www.inflearn.com


▣ JPA의 데이터 타입 분류

* Entity 타입
 - @Entity로 정의하는 객체
 - 데이터가 변해도 식별자로 지속해서 추적가능

* 값 타입
 - int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체
 - 식별자가 없고 값만 있으므로 변경시 추적불가
 * 기본값 타입
  - 자바 기본 타입(int, double)
  - 생명주기를 Entity의 의존
  - 값 타입은 공유하면X
  (회원 이름을 변경했는데 다른 회원 이름도 변경될시)
  - 래퍼 클래스(Integer, Long)
  - String
 * 임베디드 타입(embedded type, 복합 값타입)
 * 컬렉션 값 타입

 

 

 

▣ 임베디드 타입

 * 새로운 값 타입을 직접 정의할 수 있음

 * JPA는 임베디드 타입이라고 함.

 * 주로 기본 값 타입을 모아서 마늗ㄹ어서 복합값 타입이라고도 함.

 * int, String과 같은 값 타입

 * 재사용이 가능하며 높은 응집도

 * Period.isWork()처럼 해당 값 타입만 사용하는 의미 있는 메소드를 만들 수 있음

 * 임베디드 타입을 포함한 모든 값 타입은, 값 타입을 소유한 Entity에 생명주기를 의존함 

 

 

 

 


▣ 임베디드 실습

 

Member

@Entity
public class Member {

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

    @Column(name = "USERNAME")
    private String username;

    // 기간
    @Embedded // Period의 @Embeddable 둘 중 하나만 사용해도 무관
    private Period workPeriod;

    // 주소
    @Embedded
    private Address homeAddress;
}

 

 

Period

@Embeddable
public class Period {

    private LocalDateTime startDate;
    private LocalDateTime endDate;

    public Period() {
    }
}

 

Address

@Embeddable
public class Address {

    private String city;
    private String street;
    private String zipcode;

    // 기본 생성자 필수
    public Address() {
    }

    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }
}

 

 

실행결과

Member member = new Member();
member.setUsername("member1");
member.setHomeAddress(new Address("city","street","10"));
member.setWorkPeriod(new Period());

memberRepository.save(member);



// 실행결과
Hibernate: 
	create table member (
	   member_id bigint not null,
	    city varchar(255),
	    street varchar(255),
	    zipcode varchar(255),
	    username varchar(255),
	    end_date timestamp,
	    start_date timestamp,
	    primary key (member_id)
	)

Hibernate: 
    insert 
    into
        member
        (city, street, zipcode, username, end_date, start_date, member_id) 
    values
        (?, ?, ?, ?, ?, ?, ?)

| 반복적으로 사용되는 것을 따로 분리했기 때문에 좀 더 객체지향으로 설계가 가능하다.

 

 

 

 

 

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

 * 임베디드 타입은 Entity의 값일 뿐이다.

 * 임베디드 타입을 사용하기 전과 후에 매핑하는 테이블은 같다.

 * 객체와 테이블을 아주 세밀하게 매핑하는것이 가능

 * 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많음

 

 


▣ 속성 재정의

// 속성 재정의 (한 Entity에서 같은 값 타입을 사용하려 할 때 )
@Embedded
@AttributeOverrides({
        @AttributeOverride(name = "city", column = @Column(name = "WORK_CITY")),
        @AttributeOverride(name = "street", column = @Column(name = "WORK_STREET")),
        @AttributeOverride(name = "zipcode", column = @Column(name = "WORK_ZIPCODE"))
})
private Address workAddress;


// 실행결과
Hibernate: 
    create table member (
       member_id bigint not null,
        city varchar(255),
        street varchar(255),
        zipcode varchar(255),
        username varchar(255),
        work_city varchar(255),
        work_street varchar(255),
        work_zipcode varchar(255),
        end_date timestamp,
        start_date timestamp,
        primary key (member_id)
    )