본문 바로가기
spring/JPA

[JPA] 고급매핑

by H.초보개발자 2023. 12. 11.
반응형

이 글은 인프런의 김영한 강사님 자바 ORM 표준 JPA 프로그래밍-기본 편 강의 내용을 바탕으로 작성되었습니다.

 

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

현업에서 실제로 JPA로 개발을 하고 있습니다. 그런 입장에서보면 지금 작성하고 있는 코드들이 어떻게 작동하는지 이해하는데 큰 도움을 주는 강의입니다. 다음은 제가 느낀 이 강의의 장점들

www.inflearn.com

도메인 모델

 

도메인 모델 상세

 

추가사항

- 상품의 종류는 음반, 도서, 영화가 있고 이후 더 확장될 수 있다.

- 모든 데이터는 등록일과 수정일이 필수다.

 

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public abstract class Item extends BaseEntity{
    @Id
    @GeneratedValue
    @Column(name = "ITEM_ID")
    private Long id;
    private String name;
    private int price;
    private int stockQuantity;
    @ManyToMany(mappedBy = "items")
    private List<Category> categories = new ArrayList<>();
}

@Inheritance 어노테이션을 설정을 해주면, 각각의 중복되는 컬럼들을 다른 테이블로 나눌것인지, 하나의 테이블로 합칠 것인지 정의를 해줄 수 있다. 예를 들면

@Entity
public class Book extends Item{
    private String author;
    private String isbn;
}

위에 엔티티는 Item을 상속받은 Book이라는 엔티티이다. 만약 Item에서 @Inheritance(strategy = InheritanceType.JOINED) 이런식으로 설정을 해주면, 테이블이 생성이될때,

 

Item

  • id
  • name
  • price
  • stockQuantity

Book

  • author
  • isbn

이렇게 각각의 테이블에 따로 정의가 된다. 하지만 @Inheritance(strategy = InheritanceType.SINGLE_TABLE) 이런식으로 정의를 하면

 

 Item

  • id
  • name
  • price
  • stockQuantity
  • author
  • isbn

이런식으로 하나의 테이블에 모든 컬럼이 다들어간다. 하지만 여기서 중요한 것은 바로 @DiscriminatorColumn 이 어노테이션인데, 만약 저런식으로 등록을 해두고, Item엔티티를 Album이나 다른테이블에서 상속을 받으면 나중에 데이터가 들어왔을때 그 데이터가 어떤 데이터인지 확인하기 힘들것이다. 예를들어,

  • id : 1
  • name : 블로그
  • price : 1000
  • stockQuantity: 5
  • author: 초보개발자
  • isbn : null

이런 데이터가 insert 되었다면 이 데이터가 Book으로 부터 들어온 데이터인지, albm으로 부터 들어온 데이터인지 구분하기 힘들다. 여기서 @DiscriminatorColumn 어노테이션을 붙이면 테이블이 만들어질때 Dtype이라는 커럼이 추가가된다. 이 컬럼에는 어떤 데이터인지 구분하기 위한 컬럼이 생성되는데, Default값으로 컬럼만 붙여놓고, Book 데이터를 insert 해주면 Dtype데이터에 Book 데이터가 insert된다.

 

@MappedSuperclass

실무에서 일을 하다보면 어떤사람이 어떤 데이터를 넣었는지, 수정했는지 등등을 체크하는 컬럼이 필요하다, 각각의 테이블에 이런 컬럼들이 중복되서 들어가게 코드를 짜면 비 효율적이니, 하나의 코드를 만든뒤 다른 엔티티에서 상속받으면 쉽게 해결이 된다.

@MappedSuperclass
public abstract class BaseEntity {
    private String createdBy;
    private LocalDateTime createDate;
    private String lastModifiedBy;
    private LocalDateTime lastModifiedDate;
}

이런식으로 공통인 객체를 하나 생성해두고,

@Entity
public class Member extends BaseEntity{

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

    @ManyToOne
    @JoinColumn(name = "TEAM_ID", insertable = false,updatable = false)
    private Team team; //일대다 양방향

    @OneToOne
    @JoinColumn(name = "LOCKER_ID")
    private Locker locker;

    @OneToMany(mappedBy = "member")
    private List<MemberProduct> memberProducts = new ArrayList<>();
}

이렇게 상속받고 테이블을 생상하면, Member 테이블에 createBy, createDate, lastModifyiedBy, lastModifiedDate 컬럼이 추가 된것을 확인할 수 있다.

반응형

'spring > JPA' 카테고리의 다른 글

[JPA] 값타입  (0) 2023.12.12
[JPA] 프록시와 연관관계 관리  (1) 2023.12.11
[JPA] 다양한 연관관계 매핑  (0) 2023.12.08
[JPA] 연관관계 매핑 기초  (2) 2023.12.07
[JPA] 엔티티 매핑  (1) 2023.11.09