API를 만드기 위해선 총 3개의 클래스가 필요하다.
클래스를 만들때 Bean을 주입받는 방식은 다음과 같이 3가지 이다.
이 중 가장 권장하는 방식은 바로 생성자로 주입 받는 방식이다. 롬복의@RequirdArgsConstructor
를 사용하면 final이 선언된 모든 필드를 인자값으로 생성자를 자동으로 생성해준다.
생성자를 직접 안쓰고 롬복 어노테이션을 쓰는 이유는 해당 클래스의 의존성 관계가 변경 될때마다 생성자 코드를 계속 해서 수정해야 하는 번거로움이 있기 때문이다.
롬복 어노테이션이 있으면 해당 컨트롤러에 새로운 서비스를 추가하거나, 기존 컴포넌트를 제거하는 등의 상황이 발생해도 생성자코드를 전혀 손대지 않아도 된다.
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
public class PostsSaveRequestDto {
private String title;
private String content;
private String author;
@Builder
public PostsSaveRequestDto(String title, String content, String author){
this.title = title;
this.content = content;
this.author = author;
}
public Posts toEntity(){
return Posts.builder()
.title(title)
.content(content)
.author(author)
.build();
}
Dto는 Entity 클래스와 거의 유사한 형태이다. 그럼에도 추가한 이유는 Entity 클래스를 절대 Request/Response 클래스로 사용해서는 안되기 때문이다.
Entity 클래스는 데이터 베이스와 맞닿은 핵심 클래스이고, Entity 클랫를 기준으로 테이블이 생성되고, 스키마가 변경된다. 화면 변경은 아주 사소한 기능 변경인데, 이를 위해 테이블과 연결된 Entity 클래스를 변경 하는것은 너무 큰 변경이다.
따라서 View Layer와 DB Layer의 역할 분리를 철저하게 하는게 좋다.
보통 엔티티에는 해당 데이터의 생성시간과 수정시간을 포함한다. 언제 만들어졌는지, 언제 수정되었는지 등은 차후 유지보수에 있어 중요한 정보이다. 그렇다 보니 매번 DB에 삽입 전, 갱신 전에는 날짜 데이터를 등록.수정 하는 코드가 들어가게 된다.
Java8부터 LocalDate와 LocalDateTime이 등장했다. 그 전의 java의 날짜타입인 Date의 문제점을 그대로 고친 타입이다.
java8이 나오기전에 사용되었던 Date와 Calendar 클래스는 다음과 같은 문제점이 있었다.
- 불변객체가 아니다
멀티스레드 환경에서 문제가 발생할 수 있다.- Calendar는 월 값 설계가 잘못 되있었다.
10월을 나타내는 October의 값이 9이다.
당연히 10으로 생각했던 개발자들에게는 큰 혼란이였다.
package com.jojodu.book.springboot.domain;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@Getter
@MappedSuperclass //1
@EntityListeners(AuditingEntityListener.class) // 2
public class BaseTimeEntity {
@CreatedDate // 3
private LocalDateTime createdDate;
@LastModifiedDate // 4
private LocalDateTime modifiedDate;
}
@MappedSuperclass
JPA Entity 클래스들이 BaseTimeEntity를 상송할 경우 필드를 칼럼으로 인식하도록 한다.
@EntityListeners(AuditingEntityListener.class)
BaseTimeEntity 클래스에 Auditing 기능을 포함시킵니다.
@CreatedDate
Entity가 생성되어 저장될 때 시간이 자동 저장됩니다.
@LastModifedDate
조회된 Entitiy의 값을 변경할때 시간이 자동으로 저장됩니다.