Day 3
Day3
์คํ๋ง ๋ถํธ์์ JPA๋ก ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ๋ค๋ฃจ๊ธฐ
๐JPA์ ๋ฑ์ฅ ๋ฐฐ๊ฒฝ
JPA๋ผ๋ ์๋ฐ ํ์ค ORM(Object Relational Mapping)๊ธฐ์
๊ฐ์ฒด๋ฅผ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ด๋ฆฌํ๋ ๊ฒ
๋จ์ SQL๋ฌธ์ ์ฌ์ฉํ ๋ฌธ์
SQL๋ฌธ์ ๋จ์ํ ๋ฐ๋ณต ์์ ์ด ๋๊ณ , ์ด๋ ํผํ ์ ์๋ค
ํจ๋ฌ๋ค์ ๋ถ์ผ์น
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ง์ ์ด์ฒจ์ด ๋ง์ถฐ์ง๊ธฐ์
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ๋ฉ์ธ์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฅ๊ณผ ์์ฑ์ ํ ๊ณณ์์ ๊ด๋ฆฌํ๋ ๊ธฐ์
๊ฐ์ฒด๋ฅผ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ ค๊ณ ํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ณ ์ด๋ฅผ ํจ๋ฌ๋ค์ ๋ถ์ผ์น๋ผ๊ณ ํจ
JPA๋ ์ค๊ฐ์์ ํจ๋ฌ๋ค์์ ์ผ์น์์ผ์ฃผ๊ธฐ ์ํ ๊ธฐ์
= ๊ฐ๋ฐ์๋ ๊ฐ์ฒด์งํฅ์ ์ผ๋ก ํ๋ก๊ทธ๋๋ฐ์ ํ๊ณ , SQL์ ์ข ์์ ์ธ ๊ฐ๋ฐ์ ํ์ง ์์๋ ๋๋ค
๐Spring Data JPA๋?
JPA๋ ์ธํฐํ์ด์ค๋ก์ ์๋ฐ ํ์ค ๋ช ์ธ์์ด๋ค. ์ธํฐํ์ด์ค์ด๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๊ตฌํ์ฒด๊ฐ ํ์ํจ( ex - Hibernate, Eclipse ๋ฑ) โ ํ์ง๋ง Spring์์ JPA๋ฅผ ์ฌ์ฉํ ๋๋ ์ด ๊ตฌํ์ฒด๋ฅผ ์ง์ ๋ค๋ฃจ์ง ์์
JPA โ Hibernate โ Spring Data JPA
Spring Data JPA์ ๋ฑ์ฅ ๋ฐฐ๊ฒฝ
๊ตฌํ์ฒด ๊ต์ฒด์ ์ฉ์ด์ฑ
=Hibernate ์ธ์ ๋ค๋ฅธ ๊ตฌํ์ฒด๋ก ์ฝ๊ฒ ๊ต์ฒดํ๊ธฐ ์ํจ
์๋ก์ด ๊ตฌํ์ฒด๊ฐ ๋์์ ๊ต์ฒดํ ํ์๊ฐ ์์ ๋ ์ฝ๊ฒ ๊ต์ฒด๊ฐ๋ฅ
์ ์ฅ์ ๊ต์ฒด์ ์ฉ์ด์ฑ
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ์ ๋ค๋ฅธ ์ ์ฅ์๋ก ์ฝ๊ฒ ๊ต์ฒดํ๊ธฐ ์ํจ
๋ง์ฝ mongoDB๋ก ๊ต์ฒดํ ํ์๊ฐ ์๋ค๋ฉด ์์กด์ฑ๋ง ๊ต์ฒดํด์ฃผ๋ฉด ๋๋ค
JPA๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ๋ ๊ฐ์ฅ ํฐ ์ด์ ๋ ์ด๋ ค์์ : ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ๊ณผ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ ์ดํดํด์ผํจ
์์ผ๋ก ๋ง๋ค ๊ฒ์ํ์ ์๊ตฌ์ฌํญ ๋ถ์
๊ฒ์ํ ๊ธฐ๋ฅ
๊ฒ์ํ ์กฐํ
๊ฒ์๊ธ ๋ฑ๋ก
๊ฒ์๊ธ ์์
๊ฒ์๊ธ ์ญ์
ํ์๊ธฐ๋ฅ
๊ตฌ๊ธ/๋ค์ด๋ฒ ๋ก๊ทธ์ธ
๋ก๊ทธ์ธํ ์ฌ์ฉ์ ๊ธ ์์ฑ ๊ถํ
๋ณธ์ธ ์์ฑ ๊ธ์ ๋ํ ๊ถํ ๊ด๋ฆฌ
ํ๋ก์ ํธ์ Spring Data JPA ์ ์ฉํ๊ธฐ
build.gradle
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
annotationProcessor("org.projectlombok:lombok")
compileOnly("org.projectlombok:lombok")
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
spring-boot-starter-data-jpa
์คํ๋ง ๋ถํธ์ฉ Spring Data JPA ์ถ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์คํ๋ง ๋ถํธ ๋ฒ์ ์ ๋ง์ถฐ ์๋์ผ๋ก JPA๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ๋ฒ์ ์ ๊ด๋ฆฌ
h2
์ธ๋ฉ๋ชจ๋ฆฌ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค
๋ณ๋์ ์ค์น๊ฐ ํ์ ์์ด ํ๋ก์ ํธ ์์กด์ฑ๋ง์ผ๋ก ๊ด๋ฆฌ ๊ฐ๋ฅ
๋ฉ๋ชจ๋ฆฌ์์ ์คํ๋๊ธฐ ๋๋ฌธ์ ์ฑ ์ฌ์์์ ์ด๊ธฐํ(ํ ์คํธ ์ฉ๋๋ก ๋ง์ด ์ฌ์ฉ)
src/main/java/com/kyu/book/springboot์ domainํจํค์ง ์์ฑ
๋๋ฉ์ธ = sw์ ๋ํ ์๊ตฌ์ฌํญ ํน์ ๋ฌธ์ ์์ญ
domain๋ด๋ถ์ ๊ฒ์๋ฌผ(post)๋ฅผ ์ํ Post.class์์ฑ
src/main/java/com/kyu/book/springboot/domain/posts/Posts.class
package com.kyu.book.springboot.domain.posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor
@Entity
public class Posts {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length=500, nullable = false)
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder
public Posts(String title, String content, String author){
this.title = title;
this.content = content;
this.author = author;
}
}
@Entity
ํ ์ด๋ธ๊ณผ ๋งํฌ(๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ)๋ ํด๋์ค์์ ๋ํ๋
SalesManager.java โ sales_manager table
์ด๋ฐ ์์ผ๋ก db์ ์ด๋ฆ์ ์ง๋๋ค
@Id
ํด๋น ํ ์ด๋ธ์ Primary Key ํ๋๋ฅผ ๋ํ๋ ๋๋ค
@GeneratedValue
Primary Key์ ์์ฑ ๊ท์น์ ๋ํ๋
์คํ๋ง ๋ถํธ 2.0์์๋ GenerationType.IDENTITY ์ต์ ์ ์ถ๊ฐํด์ผ๋ง auto_increment๊ฐ ๋จ
@Column
ํ ์ด๋ธ์ ์นผ๋ผ์ ๋ํ๋ด๋ฉฐ ๊ตณ์ด ์ ์ธํ์ง ์๋๋ผ๋ ํด๋น ํด๋์ค์ ํ๋๋ ๋ชจ๋ ์นผ๋ผ์ด ๋จ
์ฌ์ฉํ๋ ์ด์ ๋, ๊ธฐ๋ณธ๊ฐ ์ธ์ ์ถ๊ฐ๋ก ๋ณ๊ฒฝ์ด ํ์ํ ์ต์ ์ด ์์ผ๋ฉด ์ฌ์ฉํฉ๋๋ค
๋ฌธ์์ด์ ๊ฒฝ์ฐ์๋ varchar(255)๊ฐ ๊ธฐ๋ณธ๊ฐ์ธ๋ฐ, ์ฌ์ด์ฆ๋ฅผ 500์ผ๋ก ๋๋ฆฌ๊ฑฐ๋ / ํ์ ์ ๋ณ๊ฒฝํ๊ณ ์ถ์๋ ์ฌ์ฉ
@NoArgsConstructor
๊ธฐ๋ณธ ์์ฑ์ ์๋์ผ๋ก ์ถ๊ฐ
public Posts(){}์ ๊ฐ์ ํจ๊ณผ
@Getter
ํด๋์ค ๋ด ๋ชจ๋ ํ๋์ Getter ๋ฉ์๋๋ฅผ ์๋ ์์ฑ
@Builder
ํด๋น ํด๋์ค์ ๋น๋ ํจํด ํด๋์ค๋ฅผ ์์ฑ
์์ฑ์ ์๋จ์์ ์ ์ธ ์ ์์ฑ์์ ํฌํจ๋ ํ๋๋ง ๋น๋์ ํฌํจ
*Entity์ primarykey๋ Longํ์ ์ auto_increment๋ฅผ ์ถ์ฒ
*Entity์๋ ์ ๋๋ก Setter ๋ฉ์๋๋ฅผ ๋ง๋ค์ง ์๋๋ค
์ธ์คํด์ค ๊ฐ๋ค์ด ์ธ์ ์ด๋์ ๋ณํ๋๋์ง ์ฝ๋์์ผ๋ก ๋ช ํํ๊ฒ ๊ตฌ๋ถํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฐจํ ๊ธฐ๋ฅ ๋ณ๊ฒฝ์ ๋ฌธ์ ๊ฐ ์๊น
ํด๋น ํ๋์ ๊ฐ ๋ณ๊ฒฝ์ด ํ์ํ๋ฉด ๋ช ํํ ๊ทธ ๋ชฉ์ ๊ณผ ์๋๋ฅผ ๋ํ๋ผ ์ ์๋ ๋ฉ์๋๋ฅผ ์ถ๊ฐํด์ผํจ
๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ
์์ฑ์๋ฅผ ํตํด ์ต์ข ๊ฐ์ ์ฑ์ด ํ DB์ ์ฝ์ ํ๋ค. ๋ํ ๊ฐ ๋ณ๊ฒฝ์ด ํ์ํ ๊ฒฝ์ฐ ํด๋น ์ด๋ฒคํธ์ ๋ง๋ public ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ณ๊ฒฝ
์ฌ๊ธฐ์๋ @Builder๋ฅผ ํตํด ์ ๊ณต๋๋ ๋น๋ ํด๋์ค๋ฅผ ์ฌ์ฉ, ๋น๋ ํจํด์ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉํจ
๐Postsํด๋์ค๋ก DB์ ์ ๊ทผํ๊ธฐ ์ํ JpaRepository๋ฅผ ์์ฑ
src/main/java/com/kyu/book/springboot/domain/posts/PostsRepository.interface
package com.kyu.book.springboot.domain.posts;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostsRepository extends JpaRepository<Posts, Long> {
}
JPA์์๋ Repository๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ ์ธํฐํ์ด์ค๋ก ์์ฑ
JpaRepository<Entityํด๋์ค, primary key ํ์ >์ ์์ํ๊ฒ ๋๋ฉด ๊ธฐ๋ณธ์ ์ธ CRUD ๋ฉ์๋๊ฐ ์๋์ผ๋ก ์์ฑ
@Repository๋ฅผ ์ถ๊ฐํ ํ์ ์์ โ Entityํด๋์ค์ ๊ธฐ๋ณธ Entity Repository๋ ํจ๊ป ์์น
๐Spring Data JPA ํ
์คํธ ์ฝ๋ ์์ฑํ๊ธฐ
src/test/java/com/kyu/book/springboot/domain/posts/PostRepositoryTest.class
package com.kyu.book.springboot.web.domain.posts;
import com.kyu.book.springboot.domain.posts.Posts;
import com.kyu.book.springboot.domain.posts.PostsRepository;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PostsRepositoryTest {
@Autowired
PostsRepository postsRepository;
@After
public void cleanup(){
postsRepository.deleteAll();
}
@Test
public void postsSave_Load(){
String title = "ํ
์คํธ ๊ฒ์๊ธ";
String content = "ํ
์คํธ ๋ณธ๋ฌธ";
postsRepository.save(Posts.builder()
.title(title)
.content(content)
.author("kyudo97@naver.com").build());
List<Posts> postsList = postsRepository.findAll();
Posts posts = postsList.get(0);
assertThat(posts.getTitle()).isEqualTo(title);
assertThat(posts.getContent()).isEqualTo(content);
}
}
@After
Junit์์ ๋จ์ ํ ์คํธ๊ฐ ๋๋ ๋๋ง๋ค ์ํ๋๋ ๋ฉ์๋๋ฅผ ์ง์
๋ณดํต์ ๋ฐฐํฌ ์ ์ ์ฒด ํ ์คํธ๋ฅผ ์ํํ ๋ ํ ์คํธ ๊ฐ ๋ฐ์ดํฐ ์นจ๋ฒ์ ๋ง๊ธฐ ์ํด ์ฌ์ฉ
์ฌ๋ฌ ํ ์คํธ๊ฐ ๋์์ ์ํ๋๋ฉด ํ ์คํธ์ฉ db์ธ H2์ ๋ฐ์ดํฐ๊ฐ ๊ทธ๋๋ก ๋จ์ ์์ด์ ๋ค์ ํ ์คํธ ์คํ ์ ํ ์คํธ ์คํจํ ์ ์์
postsRepository.save
ํ ์ด๋ธ posts์ insert/update ์ฟผ๋ฆฌ๋ฅผ ์คํ
id๊ฐ์ด ์๋ค๋ฉด update๊ฐ / ์๋ค๋ฉด insert ์ฟผ๋ฆฌ๊ฐ ์คํ
postsRepository.finaAll
ํ ์ด๋ธ posts์ ์๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์กฐํํด์ค๋ ๋ฉ์๋
์ฌ๊ธฐ์ ์ค์ ๋ก ์คํ๋ ์ฟผ๋ฆฌ๋ ์ด๋ค ํํ์ผ๊น??
โ ํ ์ค์ ์ฝ๋๋ก ์ค์ ํ ์ ์์
src/main/resources ๋๋ ํ ๋ฆฌ ์๋์
resourceํ์ผ ํํ, application์ด๋ฆ์ ํ์ผ์ ๋ง๋ ๋ค
src/main/resources/application.properties
spring.jpa.show_sql=true
์ด๋ ๊ฒ ์ต์ ์ ์ถ๊ฐํด์ฃผ๋ฉด
๋ก๊ทธ์์ ์ฟผ๋ฆฌ๋ฅผ ํ์ธ ํ ์ ์์
+MySQL๋ฒ์ ์ผ๋ก ๋ณ๊ฒฝํ๊ธฐ ์ํด์ ์ถ๊ฐ
spring.jpa.show_sql=true
spring.jpa.properties.hibernate.dialect=
org.hibernate.dialect.MySQL5InnoDBDialect
Last updated
Was this helpful?