~3.3 DTO를 데이터 베이스에 저장하기(종이책 p97~126)
폼 데이터(form data)란 HTML 요소인 <form> 태그에 실려 전송되는 데이터를 말한다.
<form>태그는 택배와 같이 데이터를 전송할 때 어디로, 어떻게 보낼지 등을 적어서 보낸다.
<form>태그에 실어 보낸 데이터는 서버의 컨트롤러가 객체에 담아 받는다. 이 객체를 DTO(Data Transfer Object)라고 하고, DTO로 받은 데이터는 최종적으로 데이터베이스에 저장된다.
입력 폼 만들기
<form></form> 태그를 작성하고 게시판의 제목을 입력할 <input>태그, 내용을 입력할 <textarea>태그, 전송 버튼인 <button>태그를 추가하고 버튼의 속성을 type=”submit”으로 설정 {{>layouts/header}}
<form action=””>
<input type=”text”>
<textarea></textarea>
<button type=”submit”>Submit</button>
</form>
{{>layouts/footer}}
컨트롤러 만들기
컨트롤러 만들기

{{>layouts/header}}
<form class=”container”>
<div class=”mb-3”>
<label calss=”form-label”>제목</label>
<input type=”text” class=”form-control”>
</div>
<div class=”mb-3”>
<label class=”form-label”>내용</label>
<textarea class=”form-control” rows=”3”></textarea>
</div>
<button type=”submit” class=”btn btn-primary”>Submit</button>
</form>
{{>layouts/footer}}

폼 데이터 전송하기
<form> 태그를 입력할 때 필요한 2가지 정보(데이터를 어디로, 어떻게 보낼것인지)를 주지 않았기 때문에localhost:8080/articles/new 페이지에서 제목과 내용을 입력하고 Submit 버튼을눌러도 아무 일이 일어나지 않는다.
<form> 태그에 2가지 정보 추가하기. 어디에 보낼지는 action 속성으로, 어떻게 보낼지는 method 속성으로 설정<form class=”container” action=”/articles/create” method=”post”>
폼 데이터 받기
ArticleController를 열고 다음과 같이 코드 수정
<form> 태그에 action=”/articles/create”로 설정했으므로 @PostMapping(”/articles/create”)로 작성한다.DTO 만들기
package com.example.firstproject.dto;
public class ArticleForm {
private String title; // 제목을 받을 필드
private String content; // 내용을 받을 필드
}
폼 데이터를 DTO에 담기
입력 폼과 DTO 필드 연결하기
선언해준 필드 title과 content에 값이 들어가려면 new.mustache 입력 폼에 필드명을 지정해 줘야 한다. 그래야 해당 입력 폼이 DTO의 필드과 연결된다.
<input> 태그에 name=”title” 속성을 추가한다.<textarea> 태그에 name=”content” 속성을 추가한다.브라우저에서 제목과 내용을 입력하고 Submit 버튼을 클릭하면 인텔리제이 콘솔창에서 프린트문으로 출력된 것을 확인할 수 있다.
데이터베이스(DB)란 데이터를 관리하는 창고이다. DB의 모든 데이터는 행과 열로 구성된 테이블(table)에 저장해 관리한다.
여기서는 H2 DB를 사용한다.
DB는 SQL(Structured Query Language)이라는 언어를 사용하기 때문에 자바 언어를 이해하지 못한다. 따라서 JPA(Java Persistence API)라는 도구를 이용해 자바 언어로 DB에 명령을 내려야 한다.
JPA의 핵심 도구로는 엔티티(entity)와 리파지터리(repository)가 있다.
DTO로 받은 폼 데이터를 DB에 저장하기 위해 다음과 같은 과정으로 이루어진다.
DTO를 엔티티로 변환하기
ArticleController의 createArticle메서드에 작성한다.
DTO를 엔티티로 변환하기 위해 form 객체의 toEntity()라는 메서드를 호출해서 그 반환값을 Article 타입의 article 엔티티에 저장한다.
Article 클래스 만들기
a. 빨간색으로 표시된 Article 클래스에 마우스를 올리고 기다린 후 Create class ‘Article’을 클릭한 후, 패키지 생성 위치를 com.example.firstproject.entity로 설정한다.
• com.example.firstproject 아래에 entity 패키지가 생성되고 패키지 내부에 Article 클래스가 만들어진다.
b. Article 클래스 코드 작성
ⅰ. 이 클래스가 엔티티임을 선언하기 위해 @Entity 어노테이션을 붙인다.
• @Entity는 JPA에서 제공하는 어노테이션으로, 이 어노테이션이 붙은 클래스를 기반으로 DB에 테이블이 생성되고, 테이블 이름은 클래스 이름과 동일하게 Article로 생성된다.
ⅱ. DTO에서 작성한 것과 같이 title, content필드를 선언한다. 두 필드를 DB에서 인식할 수 있도록 @Column 어노테이션을 붙인다.(두 필드가 DB테이블의 각 열과 연결된다)
ⅲ. 엔티티의 대표값을 넣는다.
• 대푯값을 id로 선언하고 @Id 어노테이션을 붙인다.
• @GeneratedValue 어노테이션도 붙여서 대푯값을 자동으로 생성하게 한다.
ⅳ. Article 객체의 생성 및 초기화를 위해 생성자를 추가하고 toString()메서드도 추가한다.
• 둘 다 마우스 오른쪽 클릭 후 Generate로 생성할 수 있다.

toEntity() 메서드 추가하기
a. 빨간색으로 표시된 toEntity()에 마우스를 올리고 기다린 후 Create method ‘toEntity’ in ‘ArticleForm’을 클릭한다.
b. toEntity() 메서드에서는 폼 데이터를 담은 DTO 객체를 엔티티로 반환한다.(return new Article();).
• 전달값은 Article 클래스의 생성자 형식에 맞게 작성하면 된다.
• Article.java에서 생성자가 id, title, content를 매개변수로 받고 있고, ArticleForm 객체에 id정보는 없으므로 (null, title, content)를 전달한다.
public Article toEntity() {
return new Article(null, title, content);
}
리파지터리로 엔티티를 DB에 저장하기
ArticleController에 articleRepository 객체 선언
private ArticleRepository articleRepository;
articleRepository.save() 메서드를 호출해 article 엔티티를 저장
Article saved = articleRepository.save(article);
리파지터리 만들기
com.example.firstproject에 repository 패키지 추가
repository 패키지에 오른쪽 마우스를 누르고 New→Java Class를 선택하고 Interface를 선택해서 ArticleRepository 인터페이스를 만든다.
리파지터리는 사용자가 직접 구현할 수도 있지만 JPA에서 제공하는 리파지터리 인터페이스를 활용해 만들 수도 있다. ArticleRepository 다음에 extends Crud를 입력하고 CrudRepository<T, ID>를 선택하면 CrudRepository라는 인터페이스를 상속받는다.
CrudRepository를 상속해 엔티티를 관리(생성, 조회, 수정, 삭제)할 수 있다. CrudRepository에 홑화살괄호(<>)를 붙이고 다음과 같이 2개의 제네릭 요소를 받는다.
public interface ArticleRepository extends CrudRepository<Article, Long> {}
※ 여기까지 작성하면 CrudRepository가 제공하는 기능을 별도 정의 없이 사용할 수 있다. DB에 데이터를 생성하고(Create), 읽고(Read), 수정하고(Update), 삭제하는(Delete) 기본 동작을 추가 코드로 구현할 필요 없이 상속받아서 사용할 수 있다.
객체 주입하기
데이터 저장 확인하기