반응형

1. @MappedSuperClass

 

회사 정보를 조회하는 사이트를 구축한다고 해보자.

 

 

회사 테이블에도 생성일, 수정일을 넣어야하고

유저에도 개인정보 수정일, 가입일 (createdDate)를 넣어야하는데

지금은 2개의 테이블이지만 생성/수정일을 몇십개의 테이블에 다 넣어야한다면, 저짓을 겁나많이해야된다.

너무귀찮은일임.

 

@Enttiy
public class Company {
	@Id @GeneratedValue
	private Long id;
    private String name;
    private String address;
    private LocalDateTime createdDate;
    private String createdBy;
    private LocalDateTime updatedDate;
    private String updatedBy;
}

@Entity
public class User {
	@Id @GeneratedValue
	private Long userId;
    private String name;
    private String mobile;
    private String email;
    private LocalDateTime createdDate;
    private String createdBy;
    private LocalDateTime updatedDate;
    private String updatedBy;
}

보기만 해도 토가나온다.

 

이것을 안하기위해서 MappedSuperClass 를 써보자

BaseEntity 라는 이름을 써서 만들어줄것임

@MappedSuperClass
public abstract class BaseEntity {
	private LocalDateTime createdDate;
    private String createdBy;
    private LocalDateTime updatedDate;
    private String updatedBy;
}

주의할점은 abstract 로 작성해야된다는점임.

 

이제 이것을 붙여보면

@Enttiy
public class Company extends BaseEntity {
	@Id @GeneratedValue
	private Long id;
    private String name;
    private String address;
}

@Entity
public class User extends BaseEntity {
	@Id @GeneratedValue
	private Long userId;
    private String name;
    private String mobile;
    private String email;
}

짠~

가독성으로만 따져봐도 중요한 변수만 보임!

 

근데 사이트가 커져서, 회사를 업종별로 select 하고싶어졌다...

별도로 관리를 해줘야한다면? company를 업종별로 나눠야겠지

 

근데, 어짜피 이름 주소 ...등등 기본적인건 다 쓰니까 그대로두고

업종 + 업종별 unique 컬럼들만 쏙쏙 빼서 관리하고싶다면???

 

2.@inherited & @DiscriminatorColumn

 

company 에 pk로 company_id 넣어주고

dtype 이라는 컬럼으로 자식들 구분값 fk로 넣어주는식으로 해야 나중에 select 해올때 dtype 값으로 join 해서 가져오겠지.

 

이것을 JPA로 구현해보자

 

일단 기본이 되는 COMPANY 를 생성

@Enttiy
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Company extends BaseEntity {
	@Id @GeneratedValue
    @Column(name = "COMPANY_ID")
	private Long id;
    private String name;
    private String address;
}

새로보는 애노테이션이 있쥬??

@Inheritance 의 InheritanceType 전략에 따라 다양한 테이블을 만들수있음.

지금만드려는건 join 형태의 테이블이니까 JOIN을 쓰지만, SINGLE_TABLE, TABLE_PER_CLASS 전략이 있는데

다른애들은 테이블통째로 만들어서 별로다.

 

@Inheritance 로 전략을 설정하고

@DiscriminatorColumn으로 부모가 누군지 알려준다. 나대지 못하도록.

글고 부모테이블 (company)에 자식들 구분값을 넣어주는 컬럼을 생성해준다.

DTYPE 이라는 이름으로 자동값으로 생성되는데 이름을 바꿔줘도되지만, 보통은 이걸로 쓰는거같다.

 

그리고 자식을 만들어주자

 

@Entity
@DiscriminatorValue("O")
public class Office extends Company {
	@Id @GeneratedValue
    	private Long officeId;
    
    	private String businessType;
    	private String ceo;
    
}

@Entity
@DiscriminatorValue("S")
public class Store extends Company {
	@Id @GeneratedValue
    	private Long storeId;
    
    	private String businessType;
    	private String cto;
    
}

@Entity
@DiscriminatorValue("R")
public class Restorant extends Company {
	@Id @GeneratedValue
    	private Long restorantId;
    
    	private String businessType;
    	private String chef;
    
}

 

자식은 테이블 따로만들꺼니까 @Entity 달아주고

자식에겐 이름을 지어줘야지.

 

@DiscriminatorValue 로 이름을 지어준다.

이렇게하면 부모의 DTYPE 컬럼에 discriminatorValue로 설정한 문자들이 박히게된다.

 

 

자 여기까지 하면 상속은 왠만한건 다 끝난것같지만? 갑자기 이런녀석도있다.

 

3. @Embedded

 

이녀석도 상속하는녀석인데... 대체 님 뭐임?

 

@MapperSuperClass 형님 어쩔깝쇼??

일단 형님의 특징은 아래와같다.

 

@Entity 로 선언된 엔티티 클래스는 같은 엔티티클래스 혹은 @MapperSuperClass 로 지정된 클래스만 상속이 가능하다.

형님은 부모클래스는 자식클래스에 매핑정보만 제공하는 역할이다.

또한 단독으로 사용되는 일이 없으므로 추상클래스로 사용하는게 좋고

전체 엔티티에서 공통으로 적용하는 정보를 모을때 사용한다

 

그럼 샛병아리 @Embedded 는?

 

@Getter @Setter
@Embeddable
public class Times {
	private LocalDateTime createdDate;
    	private LocalDateTime updatedDate;
}

일단 냅다 만들고

전 쓰여지는 애입니다~ 하는 Embeddable 애노테이션을 달아준다.

 

@Entity
public class User {

	@Id
	@GeneratedValue
	private Long id;
	private String name;

	@Embedded
	private Times times;
}

그리고 쓰는곳에서 변수중에 임베디드 할 녀석을 지정해준다.

이렇게되면 @MappedSuperClass 성님처럼 부모노릇은 못하고 노예처럼 사용되게된다 후후

 

형님은 상속을, 저 햇병아리는 위임을 사용하는것의 차이인데

 

형님은 감히 우리가 사용하진 못한다. 변경할수가없다.

 

하지만 임베디드 햇병아리는 변수값을 변경시키거나 사용할때 용이하다. 한 딱까리 한다.

 

임베디드는 햇병아리답게 사용할때도 좀 복잡하다.

jpql을 쓴다고하면

select u from User u where u.times.createdDate

이렇게 쩜을 겁나찍어줘야됨.

 

하지만 우리 형님은?

 

select u from User u where u.createdDate

직관성좋게 한줄이면 된다.

 

편리함과직관성때문에 조회시에는 형님을, 수정이 필요할때는 임베디드를 사용하면된다.

 

 

 

이해에 도움을 준 블로그 

https://velog.io/@rudwnd33/JPA-MappedSuperclass-vs-Embedded-Type

728x90

+ Recent posts