Spring/Spring Data JPA

[Spring Data JPA] 3. 엔티티 Value 관계 맵핑

미스터로즈 2021. 8. 8. 17:00

백기선님 강의 중 Spring Data JPA에 대해서 정리를 해놓은 블로그입니다.

자세한 내용은 강의를 참고해주세요.

강의 링크

 


앤티티 맵핑

@Entity

  • “엔티티”는 객체 세상에서 부르는 이름.
  • 보통 클래스와 같은 이름을 사용하기 때문에 값을 변경하지 않음.
  • 엔티티의 이름은 JQL에서 쓰임.

 

@Table

  • “릴레이션" 세상에서 부르는 이름.
  • @Entity의 이름이 기본값.
  • 테이블의 이름은 SQL에서 쓰임.

 

@Id

  • 엔티티의 주키를 맵핑할 때 사용.
  • 자바의 모든 primitive 타입과 그 랩퍼 타입을 사용할 수 있음
  • Date랑 BigDecimal, BigInteger도 사용 가능.
  • 복합키를 만드는 맵핑하는 방법도 있지만 그건 논외로..

 

@GeneratedValue

  • 주키의 생성 방법을 맵핑하는 애노테이션
  • 생성 전략과 생성기를 설정할 수 있다.
  • 기본 전략은 AUTO: 사용하는 DB에 따라 적절한 전략 선택
  • TABLE, SEQUENCE, IDENTITY 중 하나.

 

@Column

  • unique
  • nullable
  • length
  • columnDefinition

 

@Temporal

현재 JPA 2.1까지는 Date와 Calendar만 지원.

 

@Transient

  • 컬럼으로 맵핑하고 싶지 않은 멤버 변수에 사용.

 

application.properties

  • spring.jpa.show-sql=true
  • spring.jpa.properties.hibernate.format_sql=true

Value 타입 맵핑

엔티티 타입과 Value 타입 구분

  • 식별자가 있어야 하는가.
  • 독립적으로 존재해야 하는가.

 

Value 타입 종류

  • 기본 타입 (String, Date, Boolean, ...)
  • Composite Value 타입
  • Collection Value 타입
  • 기본 타입의 콜렉션
  • 컴포짓 타입의 콜렉션

 

Composite Value 타입 맵핑

  • @Embeddable
  • @Embedded
  • @AttributeOverrides
  • @AttributeOverride

1대 다 맵핑

관계에는 항상 두 엔티티가 존재 합니다.

  • 둘 중 하나는 그 관계의 주인(owning)이고
  • 다른 쪽은 종속된(non-owning) 쪽입니다.
  • 해당 관계의 반대쪽 레퍼런스를 가지고 있는 쪽이 주인.

 

단방향에서의 관계의 주인은 명확합니다.

  • 관계를 정의한 쪽이 그 관계의 주인입니다.

 

단방향 @ManyToOne

  • 기본값은 FK 생성

 

단방향 @OneToMany

  • 기본값은 조인 테이블 생성
  • 양방향
  • FK 가지고 있는 쪽이 오너 따라서 기본값은 @ManyToOne 가지고 있는 쪽이 주인.
  • 주인이 아닌쪽(@OneToMany쪽)에서 mappedBy 사용해서 관계를 맺고 있는 필드를 설정해야 합니다.

 

양방향

  • @ManyToOne (이쪽이 주인)
  • @OneToMany(mappedBy)
  • 주인한테 관계를 설정해야 DB에 반영이 됩니다.

실습 해보기

앤티티 맵핑 연습

package com.whiteship;

import javax.persistence.*;
import java.util.Date;

@Entity
public class Account {

    @Id @GeneratedValue
    private Long id;

    @Column(nullable =  false,unique = true)
    private String username;

    private  String password;

    @Temporal(TemporalType.TIME)
    private Date created = new Date();

    private String yes;

    //Transient을 쓰면 컬럼으로 맵핑을 안해도 됩니다.
    @Transient
    private String no;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

 

value 타입 맵핑

package com.whiteship;

import javax.persistence.Embeddable;

@Embeddable
public class Address {
    private String street;
    private String city;
    private String state;
    private String zipCode;

}

- Embeddable를 사용해서 만들어 준 다음 엔티티에 포함시켜 사용할 수 있습니다.

 

 

관계 맵핑

package com.whiteship;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Study {

    @Id
    @GeneratedValue
    private  Long id;

    private String name;

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


}

 

    @OneToMany
    private Set<Study> studies = new HashSet<Study>();

 

  Study study = new Study();
  study.setName("Spring Data JPA");

  account.getStudies().add(study);