반응형
12-24 00:25
Today
Total
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
관리 메뉴

개발하는 고라니

[Spring Boot] @MappedSuperClass 본문

Framework/Spring Boot

[Spring Boot] @MappedSuperClass

조용한고라니 2021. 1. 14. 21:21
반응형

데이터베이스의 테이블은 종종 '시간'의 데이터를 갖는 컬럼이 존재하는 경우가 있다. 예를 들어 Board 테이블의 Reg Date라던지 Mod Date 등등..

JPA를 이용한다고 해서 예외는 아니다. MyBatis를 이용했다면 직접 SQL을 작성해서 Reg Date/Mod Date의 관련된 정보를 Insert 및 Update를 했겠지만. JPA에서는 이를 직접 관여할 필요가 없어졌다.

 

각설하고, 등록된 날짜와 수정된 날짜는 다양한 테이블에서 사용될 수 있다. 그럼 개발자의 입장에서 중복된 것은 극도로 싫어하므로 이를 하나의 엔티티에 설정해놓고 나머지 엔티티들이 상속을 받는다면 중복을 줄일 수 있지 않을까?

 

간단히 regDate와 modDate를 갖는 상속용 엔티티를 만들어보자.


이름을 BaseEntity라고 하고 'abstract class'로 생성한다.

@MappedSuperclass
@EntityListeners(value = {AuditingEntityListener.class})
@Getter
abstract class BaseEntity{

    private LocalDateTime regDate;
    private LocalDateTime modDate;
}

이제부터 여러가지 어노테이션을 추가한다.

 

@MappedSuperclass

- 해당 어노테이션이 적용된 클래스는 테이블로 생성되지 않는다. 이 클래스를 상속받은 엔티티에 매핑되는 테이블에 regDate와 modDate가 생성된다. (부모 클래스로만 사용된다. Entity 클래스가 아님)

 

@EntityListener()

- JPA에서는 엔티티 객체에 어떠한 변화가 생기는 것을 감지하는 리스너가 있다. JPA 내부에서 엔티티 객체가 생성/변경되는 것을 감지하는 역할은 AuditingEntityListener가 한다. 이를 통해 regDate와 modDate에 적절한 값이 할당된다.

 

@MappedSuperclass
@EntityListeners(value = {AuditingEntityListener.class})
@Getter
abstract class BaseEntity{

    @CreatedDate
    @Column(name = "regDate", updatable = false)
    private LocalDateTime regDate;

    @LastModifiedDate
    @Column(name = "modDate", updatable = true)
    private LocalDateTime modDate;
}

@CreateDate

- JPA에서 엔티티의 생성 시간을 처리한다.

 

@LastModifiedDate

- 최종 수정 시간을 자동으로 처리한다.

 

@Column

- 컬럼의 정보를 지정할 때 사용된다. 속성으로 updatable을 false로 지정하게 되면 생성된 컬럼 값이 변경되지 않는다. default는 true.

 

JPA를 사용하면서 AuditingEntityListener를 이용하려면 또 하나의 어노테이션을 추가해야 한다. @EnableJpaAuditing 이라는 어노테이션인데, 프로젝트의 main() 메소드가 있는 클래스에 달아주면 된다.

@SpringBootApplication
@EnableJpaAuditing
public class ClubApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClubApplication.class, args);
    }

}

 

이제 엔티티 클래스를 생성할 때 BaseEntity 추상 클래스를 상속하기만 하면 된다.

@Entity
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ClubMember extends BaseEntity{

    @Id
    private String email;

    private String password;
    private String name;

    private boolean fromSocial;
}

웹 어플리케이션을 실행하면 다음과 같은 SQL이 실행된다.

Hibernate:

create table club_member (
email varchar(255) not null,
mod_date datetime(6), //생성된 modDate
reg_date datetime(6), //regDate
from_social bit not null,
name varchar(255),
password varchar(255),
primary key (email)

) engine=InnoDB

 

<참고>

코드로 배우는 스프링 부트 웹 프로젝트

반응형
Comments