전 포스트에서는 폼으로 데이터를 받아서 바로 표시함
이번에는 데이터를 받아서 DB에 저장까지 해보자
DataBase는 데이터를 저장하는 창고
DB의 종류는 MySQL, ORACLE 등등 ..
지금은 h2를 사용함
DB가 사용하는 언어는 SQL임. 자바를 이해하지 못함
그런데 프로젝트 생성할 때 JPA를 추가했는데 이게 DB가 자바를 이해하게 해준다. 데이터 관리에 편리한 여러 기능도 제공한다.
JPA의 핵심은 Entitiy와 Repository이다
Entitiy는 자바 객체를 DB가 이해할 수 있게 만든 것이고
Repository는 이 Entitiy를 DB에 저장하는 역할이다.
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
@GetMapping("/article/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("articles/create")
public String createArticle(ArticleForm form){
System.out.println(form.toString());
// 1. DTO를 Entitiy로 변환해야한다
Article article = form.toEntitiy();
// 2. Repository에게 Entitiy를 DB안에 저장하게 한다
return "";
}
}
저번 포스트에서 사용했던 createArticle 메소드에서 ArticleForm 객체에 폼에 입력한 데이터를 받아왔다.
위에서 설명한 것처럼
1. DTO를 Entitiy로 변환
2. Repository를 이용해서 Entitiy를 DB안에 저장
위 코드를 보면 Article 클래스 (엔티티 클래스)를 form.toEntitiy()로 만드는데
Article 클래스가 아직 없고 toEntitiy 메소드도 없다.
그래서 Article 클래스를 만들어줘야함.
package com.example.firstproject.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity // 이 어노테이션을 붙여야 DB가 이 객체를 인식한다
public class Article {
@Id // 각 객체를 식별하기 위한 Id임 (주민번호 같은거)
@GeneratedValue // id를 1, 2, 3 ,.. 자동생성하기 위함
private Long id;
@Column //DB가 필드를 인식할 수 있게 해줌
private String title;
@Column
private String content;
public Article(Long id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
Article 객체는 이렇게 만든다.
DTO를 데이터베이스에서 사용하도록 만든 객체이므로 기본적으로 DTO의 필드는 있어야 한다.
그리고 기본적인 생성자, 확인하기 위한 toString을 넣었다.
@Entitiy : DB가 객체를 인식하게 함
@Column : DB가 필드값을 인식하게 함
@Id : id는 각 객체의 고유번호
@GeneratedValue : 값을 1, 2, 3 .. 자동생성
이렇게 Entitiy 객체인 Article 클래스를 만들었고, DTO를 Article로 바꾸기 위한 toEntitiy 메소드를 만들어야 한다.
toEntitiy는 빨간색으로 표시되는데, 마우스를 올리면 메소드를 생성하게 해준다. 클릭해서 만들자
package com.example.firstproject.dto;
import com.example.firstproject.entity.Article;
public class ArticleForm {
private String title;
private String content;
//생성자
public ArticleForm(String title, String content) {
this.title = title;
this.content = content;
}
@Override
public String toString() {
return "ArticleForm{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
public Article toEntitiy() {
return new Article(null,title,content);
}
}
dto는 dto 디렉토리에 ArticleForm이라는 클래스를 만들었다.
이 클래스에 toEntitiy 메소드를 만든다.
toEntitiy 메소드를 통해 Article 객체를 반환해야 한다. (Entitiy 객체)
따라서 Article 생성자를 이용해서 객체를 만들어 반환함
id값은 자동으로 생성되니까 null 전달하고 나머지 인자는 필드값 전달해주면 되겠다.
이제 에러가 다 사라졌다.
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
private ArticleRepository articleRepository;
@GetMapping("/article/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("articles/create")
public String createArticle(ArticleForm form){
System.out.println(form.toString());
// 1. DTO를 Entitiy로 변환해야한다
Article article = form.toEntitiy();
// 2. Repository에게 Entitiy를 DB안에 저장하게 한다
Article saved = articleRepository.save(article);
return "";
}
}
컨트롤러 클래스에 필드를 추가해줬다.
ArticleRepository 객체를 필드로 추가해줬는데, 아직 ArticleRepository 클래스를 정의하지는 않았다.
그리고 필드명 articleRepository를 대상으로 createArticle 메소드 내에서 save를 호출하고 있다.
ArticleRepository를 만들어야 한다.
repository 패키지를 만들고 ArticleRepository 인터페이스를 만들어준다.
리포지토리를 직접 만들수도 있는데 JPA에서 제공하는 인터페이스를 이용하면 더 쉽게 만들 수 있다.
package com.example.firstproject.repository;
import com.example.firstproject.entity.Article;
import org.springframework.data.repository.CrudRepository;
public interface ArticleRepository extends CrudRepository<Article, Long> {
}
이미 만들어놓은 인터페이스를 상속해서 쉽게 만들었다.
그리고 탬플릿이라 <>에 <엔티티 클래스 이름, 엔티티 클래스 id 자료형>
이렇게 넣어줘야 한다.
ArticleController로 와보면 에러 표시되던 부분이 다 지워졌다.
save는 기본적으로 CRUD 리포지토리에서 제공하는 메소드라서 따로 선언 안해도 된다.
그리고 컨트롤 클래스에 ArticleRepository 필드를 선언만 했지 객체를 생성하지는 않았는데 안해도 된다. 스프링부트가 알아서 해줌
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
@Autowired // 스프링부트가 미리 생성한 객체를 가져다가 연결
private ArticleRepository articleRepository;
@GetMapping("/article/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("articles/create")
public String createArticle(ArticleForm form){
System.out.println(form.toString());
// 1. DTO를 Entitiy로 변환해야한다
Article article = form.toEntitiy();
// 2. Repository에게 Entitiy를 DB안에 저장하게 한다
Article saved = articleRepository.save(article);
return "";
}
}
@Autowired 어노테이션을 달아주면 스프링부트가 만들어놓은 객체를 가져다가 자동으로 연결해준다.
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
@Autowired // 스프링부트가 미리 생성한 객체를 가져다가 연결
private ArticleRepository articleRepository;
@GetMapping("/article/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("articles/create")
public String createArticle(ArticleForm form){
System.out.println(form.toString());
// 1. DTO를 Entitiy로 변환해야한다
Article article = form.toEntitiy();
System.out.println(article.toString());
// 2. Repository에게 Entitiy를 DB안에 저장하게 한다
Article saved = articleRepository.save(article);
System.out.println(saved.toString());
return "";
}
}
코드는 다 작성했고 잘 진행되는지 확인하기 위해 println을 해서 출력해주자.
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
@Autowired // 스프링부트가 미리 생성한 객체를 가져다가 연결
private ArticleRepository articleRepository;
@GetMapping("/articles/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("articles/create")
public String createArticle(ArticleForm form){
System.out.println(form.toString());
// 1. DTO를 Entitiy로 변환해야한다
Article article = form.toEntitiy();
System.out.println(article.toString());
// 2. Repository에게 Entitiy를 DB안에 저장하게 한다
Article saved = articleRepository.save(article);
System.out.println(saved.toString());
return "";
}
}
articles/new로 매핑해야하는데 article/new로 매핑해서 오류발생했었음. 해결
제출하자 이렇게 표시된다.
먼저 엔티티 객체로 변환하고
db에 저장한다. db에 저장할때 id가 자동으로 생긴것 확인
10/14 03:59 commit