
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //스프링 데이터 JPA
runtimeOnly 'com.h2database:h2'
compileOnly 'org.projectlombok:lombok' //롬복
annotationProcessor 'org.projectlombok:lombok'
}

만들 엔티티와 매핑되는 테이블의 구조는 다음과 같다.
<domain/Article.java>
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //기본 키 자동으로 1씩 증가
@Column(name = "id", updatable = false)
private Long id;
@Column(name = "title", nullable = false) //title이라는 not null 속성인 테이블과 매핑
private String title;
@Column(name = "content", nullable = false)
private String content;
@Builder // 빌더 패턴으로 객체 생성
public Article(String title, String content) {
this.title = title;
this.content = content;
}
}
//빌더 패턴을 사용하지 않는 경우 (어느 필드에 어떤 값이 들어가는지 알기 어렵다.)
new Article("abc", "def");
//빌더 패턴을 사용하는 경우
Article.builder()
.title("abc")
.content("def")
.build();
public interface BlogRepository extends JpaRepository<Article , Long> {
}
클라이언트: POST /api/articles 요청을 서버에 보낸다.
컨트롤러 (BlogController.java): 클라이언트 요청을 받아 BlogService의 save() 메서드를 호출한다.
서비스 (BlogService.java): 비즈니스 로직을 처리한 뒤 BlogRepository의 save()를 호출한다.
리포지토리 (BlogRepository.java): DB에 데이터를 저장한다.
테스트: Postman을 사용해 요청을 보내고, BlogControllerTest.java에서 테스트 코드를 작성하여 기능을 검증한다.
<dto/AddArticleRequest.java>
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class AddArticleRequest {
private String title;
private String content;
public Article toEntity(){
return Article.builder()
.title(title)
.content(content)
.build();
}
}
+DTO(Data Transfer Object)
: 계층끼리 데이터를 교환하기 위해 사용하는 객체
(단순하게 데이터 옮기는 전달자 역할이라 비지니스 로직을 포함X)
: 컨트롤러 -> 서비스 넘어가기 전, 클라이언트로부터 받은 요청 데이터를 담는 객체.
+DAO(Data Access Object): 데이터베이스와 연결되고 데이터를 조회하고 수정하는데 사용되는 객체
(따라서 데이터 수정과 관련된 로직이 포함)
1. 사용자가 보낸 데이터(= JSON)는 왜 ENTITY로 바뀌어야 하는가?
클라이언트가 보낸 데이터(title, content)는 단순 문자열이기 때문에
DB에 저장하려면 JPA가 관리한느 ENTITY 객체로 변환해야 저장이 가능하다.
2. toEntity()는 비지니스 로직이 아닌가?
DTO는 비지니스 로직을 포함하지 않는다고 했는데, toEntity()는 비지니스 로직인가 아닌가 의문이 잠시 들었었다. 그러나 이는 단순 변환 로직이며 비지니스 로직은 검증, 계산, 조건 분기 등을 담고있어야 해서 비지니스 로직이 아니다.
<service/BlogService.java>
@RequiredArgsConstructor //final이 붙거나 @NotNull이 붙은 필드의 생성자 추가
@Service //빈으로 등록
public class BlogService {
private final BlogRepository blogRepository;
//블로그 글 추가 메서드
public Article save(AddArticleRequest request){
return blogRepository.save(request.toEntity());
}
}
해당 글은 다음 도서의 내용을 정리하고 참고한 글임을 밝힙니다.
신선영, ⌜스프링 부트 3 벡엔드 개발자 되기 - 자바 편⌟, 골든래빗(주), 2023, 384쪽