๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํด๋ณด์
๐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ JPA
๋ฐ์ดํฐ๋ฒ ์ด์ค
- DB
- ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ์ฐฝ๊ณ
- ๋ฐ์ดํฐ๋ฅผ ํ๊ณผ ์ด๋ก ๊ตฌ์ฑ๋ ํ ์ด๋ธ์ ์ ์ฅํด ๊ด๋ฆฌํ๋ค.
- DB ํ๋ก๊ทธ๋จ : MySQL, ์ค๋ผํด, ๋ง๋ฆฌ์DB, H2 DB ๋ฑ
- SQL ( Structured Query Language ) ์ธ์ด๋ฅผ ์ฌ์ฉํ๋ค.
์๋ฐ๋ก DB์ ๋ช ๋ น์ ์ด๋ป๊ฒ ๋ด๋ฆฌ๋?
์๋ฐ ์ธ์ด ( JPA : Java Persistence API ) ๋ก DB์ ๋ช ๋ น์ ๋ด๋ฆฐ๋ค. ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด ์งํฅ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๊ฒ ํด ์ค๋ค.
๐ค JPA์ ํต์ฌ ๋๊ตฌ
- ์ํฐํฐ : ์๋ฐ ๊ฐ์ฒด๋ฅผ DB๊ฐ ์ดํดํ ์ ์๊ฒ ๋ง๋ ๊ฒ, ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ์ด๋ธ์ด ๋ง๋ค์ด์ง๋ค.
- ๋ฆฌํ์งํฐ๋ฆฌ : ์ํฐํฐ๊ฐ DB ์ ํ ์ด๋ธ์ ์ ์ฅ ๋ฐ ๊ด๋ฆฌ๋ ์ ์๊ฒ ํ๋ ์ธํฐํ์ด์ค์ด๋ค.
DTO๋ก ๋ฐ์ ํผ ๋ฐ์ดํฐ๋ฅผ DB์ ์ด๋ป๊ฒ ์ ์ฅํ๋?
- DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํํ๋ค.
- ๋ฆฌํ์งํฐ๋ฆฌ๋ฅผ ์ด์ฉํด ์ํฐํฐ๋ฅผ DB์ ์ ์ฅํ๋ค.
1. DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํํ๊ธฐ
ArticleControlelr
package com.example.firstproject.controller;
import com.example.firstproject.dto.AritcleForm;
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 { //URL ์์ฒญ ์ ์.
@GetMapping("/articles/new") //๋ฉ์๋ ์์ฑ ๋ฐ ๋ฐํ๊ฐ ์์ฑ.
public String newArticleForm() {
return "articles/new";
}
@PostMapping("/articles/create") //๋ทฐ ํ์ด์ง์์ ํผ ๋ฐ์ดํฐ๋ฅผ post๋ฐฉ์์ผ๋ก ์ ์ก -> ์ปจํธ๋กค๋ฌ์์ ๋ฐ์ ๋๋ postmapping์ผ๋ก ๋ฐ์.
public String createArticle(AritcleForm form){ //ํผ ๋ฐ์ดํฐ๋ฅผ DTO๋ก ๋ฐ๊ธฐ
System.out.println("DTO ๋ฐ๊ธฐ"+form.toString()); //DTO์ ํผ ๋ฐ์ดํฐ๊ฐ ์ ๋ด๊ฒผ๋์ง ํ์ธ
//1.DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํ
Article article = form.toEntity();
//2.๋ฆฌํ์งํฐ๋ฆฌ๋ก ์ํฐํฐ๋ฅผ DB์ ์ ์ฅ
return "";
}
}
//1.DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํ
DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํํ๊ธฐ ์ํด form ๊ฐ์ฒด์ toEntity() ๋ฉ์๋๋ฅผ ํธ์ถํด์ ๊ทธ ๋ฐํ๊ฐ์ Artcle ํ์ ์ article ์ํฐํฐ์ ์ ์ฅํ๋ค.
DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํํ๋ ค๋ฉด ๋จผ์ ์ํฐํฐ ํด๋์ค๋ถํฐ ๋ง๋ค์ด์ผ ํ๋ค.
Aritcle
package com.example.firstproject.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
@Entity
public class Article {
@Id //์ํฐํฐ์ ๋ํฏ๊ฐ ์ง์ .
@GeneratedValue //์๋ ์์ฑ ๊ธฐ๋ฅ ์ถ๊ฐ (์ซ์๊ฐ ์๋์ผ๋ก ๋งค๊ฒจ์ง)
private Long id;
@Column //title ํ๋ ์ ์ธ, DB ํ
์ด๋ธ์ title ์ด๊ณผ ์ฐ๊ฒฐ.
private String title;
@Column //content ํ๋ ์ ์ธ, DB ํ
์ด๋ธ์ content ์ด๊ณผ ์ฐ๊ฒฐ.
private String content;
}
@Entity
- JPA์์ ์ ๊ณตํ๋ ์ด๋ ธํ ์ด์
- ์ด ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก DB์ ํ ์ด๋ธ์ด ์์ฑ ( ํ ์ด๋ธ ์ด๋ฆ์ ํด๋์ค ์ด๋ฆ๊ณผ ๋์ผํ๊ฒ Article๋ก ์์ฑ )
@Column
- ํ๋๊ฐ DB ํ ์ด๋ธ์ ๊ฐ ์ด๊ณผ ์ฐ๊ฒฐ
@Id
- ์ํฐํฐ ๋ํฏ๊ฐ ์ค์
- Article ์ํฐํฐ ์ค์ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ด ๊ฐ์ ๊ฒ์ด ์๋๋ผ๊ณ ๋ํฏ๊ฐ id๋ก ๋ค๋ฅธ ๊ธ์์ ๊ตฌ๋ถํ๋ค.
@GenerateValue
- ๋ํฏ๊ฐ์ ์๋์ผ๋ก ์์ฑ ex) 1,2,3...
Aritcle
package com.example.firstproject.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.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 ์์ฑ์ ์ถ๊ฐ (Article ๊ฐ์ฒด์ ์์ฑ ๋ฐ ์ด๊ธฐํ๋ฅผ ์ํด)
public Article(Long id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
//toString() ๋ฉ์๋ ์ถ๊ฐ
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
toEntity() ๋ฉ์๋ ์ถ๊ฐํ๊ธฐ
toEntity() ๋ฉ์๋
- DTO์ธ form ๊ฐ์ฒด๋ฅผ ์ํฐํฐ ๊ฐ์ฒด๋ก ๋ณํํ๋ ์ญํ
ArticleForm
package com.example.firstproject.dto;
import com.example.firstproject.entity.Article;
public class AritcleForm {
private String title; //์ ๋ชฉ์ ๋ฐ์ ํ๋.
private String content; //๋ด์ฉ์ ๋ฐ์ ํ๋.
//์ ์ก๋ฐ์ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ํ๋์ ์ ์ฅํ๋ ์์ฑ์ ์ถ๊ฐ.
public AritcleForm(String title, String content) {
this.title = title;
this.content = content;
}
//๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์๋์ง ํ์ธํ toString() ๋ฉ์๋ ์ถ๊ฐ.
@Override
public String toString() {
return "AritcleForm{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
//ํผ ๋ฐ์ดํฐ๋ฅผ ๋ด์ DTO ๊ฐ์ฒด๋ฅผ ์ํฐํฐ๋ก ๋ณํ.
public Article toEntity() {
return new Article(null,title,content);
}
}
return new Article ์ ๋ฌ๊ฐ์ Article ํด๋์ค์ ์์ฑ์ ํ์์ ๋ง๊ฒ ์์ฑํ๋ค.
id,title,content๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ๊ณ ์์ผ๋ ArticleForm ๊ฐ์ฒด์ id ์ ๋ณด๋ ์์ผ๋ฏ๋ก ์ฒซ ๋ฒ์งธ ์ ๋ฌ๊ฐ์ null, ๋ ๋ฒ์งธ ์ ๋ฌ๊ฐ title, ์ธ ๋ฒ์งธ ์ ๋ฌ๊ฐ content๋ก ํ๋ค.
//2.๋ฆฌํ์งํฐ๋ฆฌ๋ก ์ํฐํฐ๋ฅผ DB์ ์ ์ฅ
ArticleControlelr
package com.example.firstproject.controller;
import com.example.firstproject.dto.AritcleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller //์ปจํธ๋กค๋ฌ ์ ์ธ.
public class ArticleController { //URL ์์ฒญ ์ ์.
private ArticleRepository articleRepository; //๊ฐ์ฒด ์ ์ธ.
@GetMapping("/articles/new") //๋ฉ์๋ ์์ฑ ๋ฐ ๋ฐํ๊ฐ ์์ฑ.
public String newArticleForm() {
return "articles/new";
}
@PostMapping("/articles/create") //๋ทฐ ํ์ด์ง์์ ํผ ๋ฐ์ดํฐ๋ฅผ post๋ฐฉ์์ผ๋ก ์ ์ก -> ์ปจํธ๋กค๋ฌ์์ ๋ฐ์ ๋๋ postmapping์ผ๋ก ๋ฐ์.
public String createArticle(AritcleForm form){ //ํผ ๋ฐ์ดํฐ๋ฅผ DTO๋ก ๋ฐ๊ธฐ
System.out.println("DTO ๋ฐ๊ธฐ"+form.toString()); //DTO์ ํผ ๋ฐ์ดํฐ๊ฐ ์ ๋ด๊ฒผ๋์ง ํ์ธ
//1.DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํ
Article article = form.toEntity();
//2.๋ฆฌํ์งํฐ๋ฆฌ๋ก ์ํฐํฐ๋ฅผ DB์ ์ ์ฅ
Article saved = articleRepository.save(article); //article ์ํฐํฐ๋ฅผ ์ ์ฅํด Saved ๊ฐ์ฒด์ ๋ฐํ
return "";
}
}
ArticleRepository
package com.example.firstproject.repository;
import com.example.firstproject.entity.Article;
import org.springframework.data.repository.CrudRepository;
public interface ArticleRepository extends CrudRepository <Article,Long> {
}
๋ฆฌํ์งํฐ๋ฆฌ๋ ์ฌ์ฉ์๊ฐ ์ง์ ๊ตฌํํ ์๋ ์์ง๋ง JPA์์ ์ ๊ณตํ๋ ๋ฆฌํ์งํฐ๋ฆฌ ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํด ๋ง๋ค ์ ์๋ค.
ArticleRepository ๋ค์์ extends Crud...๋ฅผ ์ ๋ ฅํ๋ฉด ํผ์นจ ๋ชฉ๋ก์ด ๋ํ๋๋๋ฐ ๊ทธ์ค์์ CrudRepository<T,ID>๋ฅผ ์ ํํ๋ค.
์ด๋ CrudRepository๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ๋ ๋ช ๋ น์ด๋ค.
CrudRepository
- JPA์์ ์ ๊ณตํ๋ ์ธํฐํ์ด์ค
- ์ํฐํฐ๋ฅผ ๊ด๋ฆฌ(์์ฑ,์กฐํ,์์ ,์ญ์ )ํ ์ ์๋ค.
- CrudRepository์ <>๋ฅผ ๋ถ์ด๊ณ ๊ทธ ์์ 2๊ฐ์ ์ ๋ค๋ฆญ ์์๋ฅผ ๋ฐ๋๋ค.
- Article : ๊ด๋ฆฌ ๋์ ์ํฐํฐ์ ํด๋์ค ํ์ ์ ๋๋ค. ex)Article
- Long : ๊ด๋ฆฌ ๋์ ์ํฐํฐ์ ๋ํฏ๊ฐ ํ์ ex)Article.java ํ์ผ์ ๋ํฏ๊ฐ ํ์ ์ด id์ด๋ค. id์ ํ์ ์ Long์ด๋ฏ๋ก Long์ ์ ๋ ฅํ๋ค.
ArticleControlelr
package com.example.firstproject.controller;
import com.example.firstproject.dto.AritcleForm;
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 { //URL ์์ฒญ ์ ์.
@Autowired //์คํ๋ง ๋ถํธ๊ฐ ๋ฏธ๋ฆฌ ์์ฑํด ๋์ ๋ฆฌํ์งํฐ๋ฆฌ ๊ฐ์ฒด ์ฃผ์
.
private ArticleRepository articleRepository; //๊ฐ์ฒด ์ ์ธ.
@GetMapping("/articles/new") //๋ฉ์๋ ์์ฑ ๋ฐ ๋ฐํ๊ฐ ์์ฑ.
public String newArticleForm() {
return "articles/new";
}
@PostMapping("/articles/create") //๋ทฐ ํ์ด์ง์์ ํผ ๋ฐ์ดํฐ๋ฅผ post๋ฐฉ์์ผ๋ก ์ ์ก -> ์ปจํธ๋กค๋ฌ์์ ๋ฐ์ ๋๋ postmapping์ผ๋ก ๋ฐ์.
public String createArticle(AritcleForm form){ //ํผ ๋ฐ์ดํฐ๋ฅผ DTO๋ก ๋ฐ๊ธฐ
System.out.println("DTO ๋ฐ๊ธฐ"+form.toString()); //DTO์ ํผ ๋ฐ์ดํฐ๊ฐ ์ ๋ด๊ฒผ๋์ง ํ์ธ
//1.DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํ
Article article = form.toEntity();
//2.๋ฆฌํ์งํฐ๋ฆฌ๋ก ์ํฐํฐ๋ฅผ DB์ ์ ์ฅ
Article saved = articleRepository.save(article); //article ์ํฐํฐ๋ฅผ ์ ์ฅํด Saved ๊ฐ์ฒด์ ๋ฐํ
return "";
}
}
@Autowired
- ์คํ๋ง ๋ถํธ์์ ์ ๊ณตํ๋ ์ด๋ ธํ ์ด์
- ์ปจํธ๋กค๋ฌ์ ํ๋์ ๋ถ์ด๋ฉด ์คํ๋ง ๋ถํธ๊ฐ ๋ง๋ค์ด ๋์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ ์ฃผ์ ํ๋ค.
- ์์กด์ฑ ์ฃผ์ (DI, Dependency Injection)์ด๋ผ๊ณ ํ๋ค.
2.๋ฐ์ดํฐ ์ ์ฅ ํ์ธํ๊ธฐ
ArticleController
package com.example.firstproject.controller;
import com.example.firstproject.dto.AritcleForm;
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 { //URL ์์ฒญ ์ ์.
@Autowired //์คํ๋ง ๋ถํธ๊ฐ ๋ฏธ๋ฆฌ ์์ฑํด ๋์ ๋ฆฌํ์งํฐ๋ฆฌ ๊ฐ์ฒด ์ฃผ์
.
private ArticleRepository articleRepository; //๊ฐ์ฒด ์ ์ธ.
@GetMapping("/articles/new") //๋ฉ์๋ ์์ฑ ๋ฐ ๋ฐํ๊ฐ ์์ฑ.
public String newArticleForm() {
return "articles/new";
}
@PostMapping("/articles/create") //๋ทฐ ํ์ด์ง์์ ํผ ๋ฐ์ดํฐ๋ฅผ post๋ฐฉ์์ผ๋ก ์ ์ก -> ์ปจํธ๋กค๋ฌ์์ ๋ฐ์ ๋๋ postmapping์ผ๋ก ๋ฐ์.
public String createArticle(AritcleForm form){ //ํผ ๋ฐ์ดํฐ๋ฅผ DTO๋ก ๋ฐ๊ธฐ
System.out.println("DTO ๋ฐ๊ธฐ"+form.toString()); //DTO์ ํผ ๋ฐ์ดํฐ๊ฐ ์ ๋ด๊ฒผ๋์ง ํ์ธ
//1.DTO๋ฅผ ์ํฐํฐ๋ก ๋ณํ
Article article = form.toEntity();
System.out.println(article.toString());
//2.๋ฆฌํ์งํฐ๋ฆฌ๋ก ์ํฐํฐ๋ฅผ DB์ ์ ์ฅ
Article saved = articleRepository.save(article); //article ์ํฐํฐ๋ฅผ ์ ์ฅํด Saved ๊ฐ์ฒด์ ๋ฐํ
System.out.println(article);
return "";
}
}
http://localhost:8080/articles/new ์ ์ ์ํ๋ค


- ํผ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ๊ฐ์ฒด์ธ DTO์ title,content๊ฐ ์ ์ฅ๋๋ค.
- DTO๊ฐ ์ํฐํฐ๋ก ๋ณํ๋์ด id,title,content๊ฐ ์ ์ฅ๋๋ค.
- ๋ฆฌํ์งํฐ๋ฆฌ๊ฐ ์ํฐํฐ๋ฅผ DB์ ์ ์ฅ๋์ด saved๋ผ๋ ์ํฐํฐ ๋ณ์์ ๋ฐํํ๋ค. id๋ ์๋์ผ๋ก ์ค์ ๋ 1์ ์ถ๋ ฅํ๋ค.
- <๋์> ์ฝ๋ฉ ์์จํ์ต ์คํ๋ง ๋ถํธ 3 ์๋ฐ ๋ฐฑ์๋ ๊ฐ๋ฐ ์ ๋ฌธ
https://product.kyobobook.co.kr/detail/S000202971420
์ฝ๋ฉ ์์จํ์ต ์คํ๋ง ๋ถํธ 3 ์๋ฐ ๋ฐฑ์๋ ๊ฐ๋ฐ ์ ๋ฌธ | ํํ - ๊ต๋ณด๋ฌธ๊ณ
์ฝ๋ฉ ์์จํ์ต ์คํ๋ง ๋ถํธ 3 ์๋ฐ ๋ฐฑ์๋ ๊ฐ๋ฐ ์ ๋ฌธ |
product.kyobobook.co.kr