Back-End/Spring Boot

게시판 만들고 새 글 작성하기

psy_er 2024. 1. 5. 02:46
728x90

게시판 만들고 새 글 작성하기

<폼태그>

폼데이터 : HTML 요소인 <form> 태그에 실려 전송되는 데이터

<form> 태그 : 웹 브라우저에서 서버로 데이터를 전송할 때 사용

 

<form> 태그에 실어 보낸 데이터는 서버의 컨트롤러가 DTO 객체에 담아 받습니다.

DTO로 받은 데이터는 최종적으로 DB에 저장됩니다.

 

 

<뷰 템플릿>

뷰 템플릿 페이지에 입력 폼을 만들기.

자바 .java 코드가 바뀔 때는 서버를 재시작해야 하지만,

머스테치 .mustache 코드가 바뀔 때는 망치 아이콘만 눌러 빌드해도 된다.

 

 

<form 태그에 2가지 정보 추가>

<form> 태그를 입력 할 때 데이터를 어디에 보낼지는 action 속성, 어떻게 보낼지는 method 속성으로 설정

 

- action 속성  

URL 연결 주소를 적어 action="/articles/create"로 설정하는 것은,

localhost:8080/articles/create 페이지로 폼 데이터를 보낸다는 의미

 

- method 속성

GET과 POST가 있다.

일단 form 태그에서는 POST 메소드를 사용한다.

 

- templates/articles/new.mustache

<form class = "container" action = "/articles/create" method = "post">

 

 

<컨트롤러가 action, method 정보를 조합해 폼 데이터 받기>

 

- controller/ArticleController.java

import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class ArticleController{

   @GetMapping("/articles/new")
   pulbic String newArticleForm(){
      return "articles/new";
   }
   @PostMapping("articles/create")  // url 요청 접수
   public String createArticle(){  // 메서드 생성 및 반환값 작성
      return "";
   }
}

 

 

<DTO 만들기>

 

DTO :  폼 데이터를 받아올 그릇

컨트롤러에서 폼 데이터를 받을 때 DTO에 담아 받는다.

 

입력 폼에서 제목과 내용을 전송 할 예정이니, DTO에도 필드 2개가 필요합니다. 

 

- dto/ArticleForm.java

package com.example.firstproject.dto;

public class ArticleForm{ // DTO에도 필드 2개가 필요하다
   private String title;  // 제목 필드
   private String content;  // 내용 필드

   public ArticleForm(String title, String content){  // 생성자
      this.title = title;
      this.content = content;
   }

   @Override  // to String()으로 데이터 확인
   public String toString(){
      return " ArticleForm{ " + " title=' " + title + '\" + " , content=' " +
      content + ' \ " + '}';
   }
}

 

 

<생성자 자동 생성>

필드 다음 행에서 마우스 오른쪽 버튼을 누르고

Generate -> Constructor 선택, 필드 선택 후 ok 누르기

 

<폼 데이터를 잘 받았는지 확인 toString()>

메서드 아래에서 마우스 오른쪽 버튼을 누르고

Generate -> toString() 선택, 필드 선택 후 ok 누르기

 

 

<폼 데이터를 DTO에 담기>

 

DTO로 만든 클래스 이름이 ArticleForm이다.

ArticleForm 타입의 form 객체를 매개변수로 선언한다.

폼에서 전송한 데이터가 DTO에 잘 담겼는지 확인하기 위해 출력문 추가.

이후 로깅으로 바꿀 예정

 

import com.example.firstproject.dto.ArticleForm; // ArticleForm 패키지 자동 임포트

@PostMapping("articles/create")  
   public String createArticle(AricleForm form){ // 폼 데이터를 DTO로 받기  
   System.out.println(form.toString()); // DTO에 폼 데이터가 잘 담겼는지 확인
      return "";
   }

 

 

<입력 폼과 DTO 필드 연결하기>

 

DTO의 title, content 필드에 값이 들어가려면

new.mustache 입력 폼에 필드명을 지정해 줘야 입력 폼이 DTO와 연결된다.

 

new.mustache

- 제목 <input> 태그에 name = "title" 속성 추가

- 내용 <textarea> 태그에 name = "content" 속성 추가

 

- templates/articles/new.mustache

<div class = "mb-3">
   <label class = "form-label"> 제목 </label>
   <input type="text" class = "form-control" name="title"> // 필드명 지정해주기
</div>
<div class = "mb-3">
   <label class = "form-label"> 내용 </label>
   <textarea class="form-control" rows = "3" name = "contnet"></textarea> // 필드명 지정해주기
</div>

 

DTO의 필드명과 동일한 이름을 name의 속성 값으로 써 주면,

입력 폼에서 작성한 두 데이터가 DTO의 해당 필드와 연결된다.

 

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

 

웹에서 전송한 폼 데이터를 컨트롤러로 받아왔다.

받아온 데이터를 데이터베이스에 저장하는 예제를 실습해보자.

 

SQL : DB가 사용하는 언어

JPA : 자바언어로 DB에 명령을 내리는 도구, 데이터를 객체 지향적으로 관리할 수 있게 해준다.

 

 

<JPA의 핵심 도구 엔티티, 리파지터리>

 

엔티티 : 자바 객체를 DB가 이해할 수 있게 만든 것, 이를 기반으로 테이블이 만들어진다

리파지터리 : 엔티티가 DB 속 테이블에 저장 및 관리 될 수 있게 하는 인터페이스

 

 

<DTO로 받은 폼 데이터를 DB에 저장하기>

 

1) DTO를 엔터티로 변환하기

 

DTO를 엔티티로 변환하기 위해 form 객체의 toEntity()라는 메서드를 호출해서,

그 반환 값을 Article 타입의 article 엔티티에 저장합니다.

 

import com.example.firstproject.entity.Article;

// 1. DTO를 엔티티로 변환
Article article = form.toEntity();   // 빨간줄이 뜬 상태로 Article, toEnitity 만들기

 

Article 클래스, 즉 Article 엔티티 만들기

- entity/Article.java

package com.example.firstproject.entity;

import jakarta.persistence.Column; // 테이블의 가 열과 연결되는 필드 선언 어노테이션
import jakarta.persistence.Entity; // 엔터티를 선언해 DB에서 테이블 생성
import jakarta.persistence.GeneratedValue; // 대표값 자동으로 생성
import jakarta.persistence.Id; // 대표값을 id로 선언

@Entity
public class Article{

   @Id
   @GeneratedValue
   private Long id;

   @Column // title 필드 선언, DB 테이블의 title 열과 연결됨
   private String title;

   @Column // content 필드 선언, DB 테이블의 content 열과 연결됨
   private String content;

   // Article 생성자 추가 Generate -> Constructor 선택
   // Article toString() 메서드 추가 Generate -> toString() 선택

}

 

 

toEntity() 메서드

- 폼 데이터를 담은 DTO 객체(ArticleForm)를 엔티티 객체(Article)로 변환

public class ArticleForm{
   public Article toEntity(){
      return new Article(null, title, content); // 폼 데이터를 담은 DTO 객체를 엔티티 객체로 return 시키기 
   }
}

 

 

 

2) 리파지터리를 이용해 엔터티를 DB에 저장하기

public class ArticleController{
   private ArticleRepository articleRepository; // 레파지토리 객체 선언

  @PostMapping("/articles/create")
   public String createArticle(ArticleForm form){
      System.out.println(form.toString());

      // 1. DTO를 엔티티로 변환
      Article article = form.toEntity();

      // 2. 리파지터리로 엔티티를 DB에 저장
      Article saved = articleRepository.save(article); // article 엔티티를 저장해 saved 객체에 반환
      return "";
   }
}

 

.save() 메서드는 저장된 엔터티를 반환한다.

 

 

<CrudeRepository>

 

인터페이스 : 자바에서 다중상속이 가능한 추상클래스이다.

CrudRepository는 JPA에서 제공하는 인터페이스로 이를 상속해 엔터티를 관리(CRUD) 할 수 있습니다.

CrudRepository에 <>를 붙여 2개의 제네릭 요소를 받을 수 있다.

 

import org.springframework.data.repository.CrudRepository;

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

 

Aritcle : 관리 대상 엔티티의 클래스 타입

Long : 엔티티의 대푯값 타입, id 값

 

CrudRepository를 정의하면 ArticleRepository는 Create(생성), Read(읽기), Upadate(수정), Delete(삭제)

기본 동작을 추가 코드로 구현할 필요 없이 상속 받아 사용할 수 있다.

 

 

<객체 주입하기>

 

스프링 부트에서는 객체를 만들지 않아도 된다. 스프링 부트가 알아서 객체를 만들기 때문.

의존성 주입 : 컨트롤러의 필드에 @Autowired 어노테이션을 붙이면 스프링 부트가 만들어 놓은 객체를 주입해준다.

 

 

1. DTO가 폼데이터를 받음

2. DTO가 엔티티로 변환되어 저장

3. 리파지터리가 엔티티를 DB에 저장해 새로운 엔티티 변수에 반환시킴

 

 

<인텔리제이 한글 깨짐 현상>

 

File -> Settings에서 Editor -> File Encodings 설정

 

1. Global Encoding, Project Encoding, Default encoding for properties files를 UTF-8로 설정 후

Apply, Ok 누르기

 

2. Help -> Edit Custom VM Options 선택해 idea64.exe.vmoptions 편집기가 열리면

맨 아래에 -Dfile.encoding=UTF-8 코드 추가

 

3. 인텔리제이 종료 후 다시 실행하면 해결

 

 

<DB 연결>

 

행 = 레코드

INSERT INTO 테이블명(속성명1, 속성명2, 속성명3, ...) VALUES (값1, 값2, 값3, ...);

 

728x90