코드 그라데이션

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

Spring/JPA 공부

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

완벽한 장면 2023. 8. 26. 01:57

임베디드 타입

 

예제

1
2

 

매핑하면

3

 

임베디드 타입 사용법

 

 

임베디드 타입의 장점

 

 

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

 


실습예제

Member (대폭 수정)

@Entity
@NoArgsConstructor
public class Member {

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

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

  private LocalDateTime startDate;
  private LocalDateTime endDate;

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

 

실행하면

 

Hibernate: 
    
    create table Member (
       MEMBER_ID bigint not null,
        city varchar(255),
        endDate timestamp,
        startDate timestamp,
        street varchar(255),
        USERNAME varchar(255),
        zipcode varchar(255),
        primary key (MEMBER_ID)
    )

 

 

이제 이걸 묶어보고 싶다.

Member 수정

@Entity
@NoArgsConstructor
public class Member {

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

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

  //기간 묶기 Period
  @Embedded
  private Period period;

  // 주소 묶기 Address
  @Embedded
  private Address address;

}

 

Period 생성 (어노테이션 유의)

@Embeddable
@NoArgsConstructor // 기본 생성자 반드시 있어야 한다.
public class Period {

  private LocalDateTime startDate;
  private LocalDateTime endDate;

  public LocalDateTime getStartDate() {
    return startDate;
  }

  public void setStartDate(LocalDateTime startDate) {
    this.startDate = startDate;
  }

  public LocalDateTime getEndDate() {
    return endDate;
  }

  public void setEndDate(LocalDateTime endDate) {
    this.endDate = endDate;
  }
}

 

 

Address 생성

@Embeddable
@NoArgsConstructor
public class Address {

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

  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;
  }
}

 

 

실행해보면

(아, 그 전에 JpaMain에 넣는 값들은 다 비웠음)

신기하게도 테이블은 그대로 유지가 된다.

 

좀 더 객체지향스럽게 활용할 수 있게 되었음.

 

이제 값을 채워보자.

Member 에 getter,setter 채워넣고

Period와 Address에는 @AllArgsConstructor 넣어줬음.

변수명도 살짝 변경

@Embedded
private Period workPeriod;

// 주소 묶기 Address
@Embedded
private Address homeAddress;

 

JPAMain

public class JpaMain {
  public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
    EntityManager em = emf.createEntityManager();

    EntityTransaction tx = em.getTransaction();
    tx.begin();

    try {

      Member member = new Member();
      member.setUsername("minji");
      member.setHomeAddress(new Address("seoul","street1","10000"));
      member.setWorkPeriod(new Period()); //여기 안에도 값을 넣으면 됨.
      em.persist(member);

      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      e.printStackTrace();
    } finally {
      em.close();
    }
    emf.close();
  }
}

 

실행 후 H2 조회해보면

잘 들어와 있음.

 


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

 

 

임베디드 타입과 연관관계

  • 아래 그림은 JPA 표준 스펙에 나와있음.

 

 

@AttributeOverride : 속성 재정의

  • 여러 개면 전자, 하나면 후자

 

예시

@Embedded
private Address homeAddress;

@Embedded
private Address workAddress;

이렇게 만들어버리면?

실행하면 에러 난다.

 

이 때 이러한 속성을 써서

  // 주소 묶기 Address
@Embedded
private Address homeAddress;

@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;

다소 좀 복잡한!

 

실행해보면 테이블이 이렇게 생성된다.

 


임베디드 타입과 null

여기까지.

728x90

'Spring > JPA 공부' 카테고리의 다른 글

값 타입의 비교  (0) 2023.08.27
값 타입과 불변 객체  (0) 2023.08.26
기본 값 타입  (0) 2023.08.26
실전 예제 - 5. 연관관계 관리  (0) 2023.08.25
고아 객체, 그리고 생명 주기  (0) 2023.08.25
Comments