길벗 코딩자율학습단 3일차

donghan378·2025년 1월 12일

3일차

~3.3 DTO를 데이터 베이스에 저장하기(종이책 p97~126)

3장 게시판 만들고 새 글 작성하기: Create

3.1 폼 데이터란

폼 데이터(form data)란 HTML 요소인 <form> 태그에 실려 전송되는 데이터를 말한다.

<form>태그는 택배와 같이 데이터를 전송할 때 어디로, 어떻게 보낼지 등을 적어서 보낸다.

<form>태그에 실어 보낸 데이터는 서버의 컨트롤러가 객체에 담아 받는다. 이 객체를 DTO(Data Transfer Object)라고 하고, DTO로 받은 데이터는 최종적으로 데이터베이스에 저장된다.

3.2 폼 데이터를 DTO로 받기

입력 폼 만들기

  1. src/main/resources/templates 디렉터리에서 articles라는 디렉터리 만들고, articles 디렉터리에 new.mustache라는 뷰 페이지 파일 만들기
  2. 다음과 같은 코드 작성하기
    • <form></form> 태그를 작성하고 게시판의 제목을 입력할 <input>태그, 내용을 입력할 <textarea>태그, 전송 버튼인 <button>태그를 추가하고 버튼의 속성을 type=”submit”으로 설정
    • header와 footer 코드 추가
	{{>layouts/header}}
		
    <form action=””>
  		<input type=”text”>
  		<textarea></textarea>
		<button type=”submit”>Submit</button>
	</form>
    
    {{>layouts/footer}}

컨트롤러 만들기

  1. src/main/java/com.example.firstproejct/controller 패키지에 ArticleController라는 클래스 만들기
  2. 다음의 코드 입력하기

컨트롤러 만들기

  1. src/main/java/com.example.firstproejct/controller 패키지에 ArticleController라는 클래스 만들기
  2. 다음의 코드 입력하기

  • articles 디렉터리를 만들고 new.mustache 뷰 페이지를 추가했으므로 파일 경로까지 포함해 return “articles/new”;로 입력
  1. 부트스트랩 CSS 코드로 예쁘게 디자인하기

{{>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}}
  • 자바(.java)코드가 바뀔 때는 서버를 재시작해야 하지만, mustache 코드가 바뀔 때는 망치 아이콘만 눌러 빌드해도 된다.

폼 데이터 전송하기

<form> 태그를 입력할 때 필요한 2가지 정보(데이터를 어디로, 어떻게 보낼것인지)를 주지 않았기 때문에localhost:8080/articles/new 페이지에서 제목과 내용을 입력하고 Submit 버튼을눌러도 아무 일이 일어나지 않는다.

  1. <form> 태그에 2가지 정보 추가하기. 어디에 보낼지는 action 속성으로, 어떻게 보낼지는 method 속성으로 설정
    • action : URL 연결 주소를 적어 action=”/articles/create”로 설정. localhost:8080/articles/create 페이지로 폼 데이터를 보낸다는 의미
    • method : 속성 값으로 get과 post 2가지 설정 가능. 여기서는 method=”post”방식으로 설정
<form class=”container” action=”/articles/create” method=”post”>

폼 데이터 받기

ArticleController를 열고 다음과 같이 코드 수정

  1. createArticle() 메서드를 추가하고 형식을 맞추기 위해 return 값에는 빈 문자로 적기
  2. URL 요청을 받기 위해 @PostMapping()사용
    • 뷰 페이지에서 폼 데이터를 post 방식으로 전송했으므로 컨트롤러에서도 @PostMapping()으로 받는다. 이때 괄호 안에는 받는 URL주소를 넣는다.
    • new.mustache에서 <form> 태그에 action=”/articles/create”로 설정했으므로 @PostMapping(”/articles/create”)로 작성한다.

DTO 만들기

  1. DTO를 작성하기 위해 com.example.firstproject에 com.example.firstproject.dto로 설정하여 dto 패키지를 만든다. (controller 패키지와 같은 레벨)
  2. 여기에 ArticleForm이라는 자바 클래스 생성
    • ArticleForm.java라는 파일이 생성되는데 이 파일이 폼 데이터를 받아올 그릇, DTO가 된다.
  3. 입력 폼에서 제목과 내용을 전송할 것이기 때문에 DTO에도 2개의 필드가 필요하므로 title과 content 필드를 선언한다.
package com.example.firstproject.dto;
  

public class ArticleForm {

	private String title; // 제목을 받을 필드

	private String content; // 내용을 받을 필드

}
  1. content 필드 다음 행에서 마우스 오른쪽 버튼을 누르고 Generate→Constructor를 선택해 생성자를 추가한다.
  2. 폼 데이터를 잘 받았는지 확인하기 위해서 toString() 메서드를 추가한다.
    • 마우스 오른쪽 버튼을 누르고 Generate→toString()을 선택한다.

폼 데이터를 DTO에 담기

  1. ArticleController의 createArticle()메서드의 매개변수로 폼에서 전송한 데이터를 받아온다.
    • DTO에서 만든 클래스 이름이 ArticleForm이므로 ArticleForm 타입의 form 객체를 배개변수로 선언한다.
  2. 폼에서 전송한 데이터가 DTO에 잘 담겼는지 확인하기 위해 출력문을 추가한다.

입력 폼과 DTO 필드 연결하기

선언해준 필드 title과 content에 값이 들어가려면 new.mustache 입력 폼에 필드명을 지정해 줘야 한다. 그래야 해당 입력 폼이 DTO의 필드과 연결된다.

  • new.mustache에 다음과 같이 속성을 추가한다.
    • 제목을 입력하는 <input> 태그에 name=”title” 속성을 추가한다.
    • 내용을 입력하는 <textarea> 태그에 name=”content” 속성을 추가한다.

브라우저에서 제목과 내용을 입력하고 Submit 버튼을 클릭하면 인텔리제이 콘솔창에서 프린트문으로 출력된 것을 확인할 수 있다.

3.3 DTO를 데이터베이스에 저장하기

데이터베이스(DB)란 데이터를 관리하는 창고이다. DB의 모든 데이터는 행과 열로 구성된 테이블(table)에 저장해 관리한다.

여기서는 H2 DB를 사용한다.

DB는 SQL(Structured Query Language)이라는 언어를 사용하기 때문에 자바 언어를 이해하지 못한다. 따라서 JPA(Java Persistence API)라는 도구를 이용해 자바 언어로 DB에 명령을 내려야 한다.

JPA의 핵심 도구로는 엔티티(entity)와 리파지터리(repository)가 있다.

  • 엔티티 : 자바 객체를 DB가 이해할 수 있게 만든 것으로, 이를 기반으로 테이블이 만들어진다.
  • 리파지터리 : 엔티티가 DB속 테이블에 저장 및 관리될 수 있게 하는 인터페이스이다.

DTO로 받은 폼 데이터를 DB에 저장하기 위해 다음과 같은 과정으로 이루어진다.

  • DTO를 엔티티로 변환하기
  • 리파지터리를 이용해 엔티티를 DB에 저장하기

DTO를 엔티티로 변환하기

ArticleController의 createArticle메서드에 작성한다.

  1. DTO를 엔티티로 변환하기 위해 form 객체의 toEntity()라는 메서드를 호출해서 그 반환값을 Article 타입의 article 엔티티에 저장한다.

  2. 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로 생성할 수 있다.

  3. 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에 저장하기

  1. ArticleController에 articleRepository 객체 선언

    private ArticleRepository articleRepository;

  2. articleRepository.save() 메서드를 호출해 article 엔티티를 저장

    • save() 메서드는 저장된 엔티티를 반환하므로 이를 Article 타입의 saved라는 객체에 받아온다.

    Article saved = articleRepository.save(article);

  3. 리파지터리 만들기

    1. com.example.firstproject에 repository 패키지 추가

    2. repository 패키지에 오른쪽 마우스를 누르고 New→Java Class를 선택하고 Interface를 선택해서 ArticleRepository 인터페이스를 만든다.

    3. 리파지터리는 사용자가 직접 구현할 수도 있지만 JPA에서 제공하는 리파지터리 인터페이스를 활용해 만들 수도 있다. ArticleRepository 다음에 extends Crud를 입력하고 CrudRepository<T, ID>를 선택하면 CrudRepository라는 인터페이스를 상속받는다.

    4. CrudRepository를 상속해 엔티티를 관리(생성, 조회, 수정, 삭제)할 수 있다. CrudRepository에 홑화살괄호(<>)를 붙이고 다음과 같이 2개의 제네릭 요소를 받는다.

      • Article : 관리 대상 엔티티의 클래스 타입. 여기서는 Article 이다.
      • Long : 관리 대상 엔티티의 대푯값 타입. id를 대푯값으로 지정했고, id의 타입은 Long이므로 Long을 입력한다.

      public interface ArticleRepository extends CrudRepository<Article, Long> {}

    ※ 여기까지 작성하면 CrudRepository가 제공하는 기능을 별도 정의 없이 사용할 수 있다. DB에 데이터를 생성하고(Create), 읽고(Read), 수정하고(Update), 삭제하는(Delete) 기본 동작을 추가 코드로 구현할 필요 없이 상속받아서 사용할 수 있다.

  4. 객체 주입하기

    • 스프링 부트에서는 객체를 만들지 않아도 된다. 스프링 부트가 알아서 객체를 만들기 때문에 @Autowired 어노테이션을 붙이면 미리 생성해 놓은 객체를 가져다 연결해 준다. 이를 의존성 주입(DI, Dependency Injection)이라고 한다.
    • 그렇기 때문에 articleRepository 객체를 만들지 않아도 된다.
  5. 데이터 저장 확인하기

    • article 엔티티가 DB에 테이블로 저장됐는지 확인하기 위해서
      • DTO가 엔티티로 잘 변환되었는지 article.toString() 메서드로 확인한다.
      • article이 DB에 잘 저장되는지 saved.toString() 메서드로 확인한다.

0개의 댓글