Table of Contents
JPA
JPA์ Spring Data JPA ๊ฐ๋ ์ ์ดํดํ๋ค.
ORM vs. SQL Mapper
- ORM์ ๊ฐ์ฒด๋ฅผ ๋งคํํ๋ ๊ฒ, ๋ํ์ ์ธ ๊ธฐ์ ๋ก๋ JPA๊ฐ ์์
- SQL Mapper๋ ์ฟผ๋ฆฌ๋ฅผ ๋งคํํ๋ ๊ฒ, ๋ํ์ ์ธ ๊ธฐ์ ๋ก๋ MyBatis๊ฐ ์์
ํจ๋ฌ๋ค์์ ๋ถ์ผ์น
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ง ์ด์ ์ ๋ง์ถ์ง๋ง
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ๋ฉ์์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ธฐ๋ฅ๊ณผ ์์ฑ์ ํ ๊ณณ์์ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ค์ฌ
JPA๋ ํจ๋ฌ๋ค์์ ๋ถ์ผ์น๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ฐ์ฒด์งํฅ์ ์ผ๋ก ํ๋ก๊ทธ๋๋ฐํ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก SQL์ ์์ฑํด ์คํํด์ฃผ๋ฏ๋ก SQL์ ์ข ์์ ์ผ๋ก ๊ฐ๋ฐํ์ง ์์๋ ๋จ
Spring Data JPA
- JPA๋ ์ธํฐํ์ด์ค, ์๋ฐ ํ์ค ๋ช ์ธ์์ด๋ฏ๋ก ๊ตฌํ์ฒด๊ฐ ํ์ํจ. ๊ตฌํ์ฒด๋ก๋ Hibernates, Eclipse Link ๋ฑ์ด ์์
- Spring Data JPA๋ ์ด ๊ตฌํ์ฒด๋ค์ ์ข ๋ ์ฝ๊ฒ ์ฌ์ฉํ๊ณ ์ ์ถ์ํํด๋์ ๊ฒ
- ์ฅ์
- ๊ตฌํ์ฒด ๊ต์ฒด์ ์ฉ์ด์ฑ: ์๋ก์ด ๊ตฌํ์ฒด๊ฐ ๋ ์ค๋ฅผ ๋ Spring Data JPA ๋ด๋ถ์์ ๊ตฌํ์ฒด ๋งคํ์ ์ง์ํด์ฃผ๋ฏ๋ก ๊ต์ฒด๊ฐ ์ฉ์ด
- ์ ์ฅ์ ๊ต์ฒด์ ์ฉ์ด์ฑ: ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ธ์ MongoDB์ ๊ฐ์ Spring Data ํ์ ๊ตฌํ์ฒด๋ค์ ๋ค๋ฅธ ์ ์ฅ์๋ก ์ฝ๊ฒ ๊ต์ฒด ๊ฐ๋ฅ
- CRUD ์ฟผ๋ฆฌ ์์ฑํ ํ์ ์์
- ๋ถ๋ชจ-์์ ๊ด๊ณ ํํ, 1:N ๊ด๊ณ ํํ ์ฉ์ด
- ์ํ์ ํ์๋ฅผ ํ๊ณณ์์ ๊ด๋ฆฌํ์ฌ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ฉ์ด
Spring Data JPA ์ ์ฉํด๋ณด๊ธฐ
์์กด์ฑ ์ถ๊ฐ ํ ์ํฐํฐ์ Repository ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ํ ์คํธํ์ฌ JPA ์ ์ฉํ๋ ๊ณผ์ ์ ์ดํด๋ณธ๋ค.
1. build.gradle์ ์์กด์ฑ ์ถ๊ฐ
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2'
๋๋ฉ์ธ ํจํค์ง: ๊ฒ์๊ธ, ๋๊ธ, ๊ฒฐ์ ๋ฑ ์ํํธ์จ์ด์ ๋ํ ์๊ตฌ์ฌํญ ํน์ ๋ฌธ์ ์์ญ
2. ์ํฐํฐ ํด๋์ค ์์ฑ
package com.oliviarla.springboot.domain.posts;
@Getter
@NoArgsConstructor
@Entity
public class Posts extends BaseTimeEntity {
@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;
}
public void update(String title, String content){
this.title=title;
this.content=content;
}
}
@Entity
- ํ ์ด๋ธ๊ณผ ๋งํฌ๋ ํด๋์ค์์ ๋ช ์
- ๊ธฐ๋ณธ๊ฐ์ผ๋ก ํด๋์ค์ CamelCase ์ด๋ฆ์ under_score ๋ค์ด๋ฐ์ผ๋ก ํ ์ด๋ธ ์ด๋ฆ ๋งค์นญ
@Id: ํด๋น ํ ์ด๋ธ์ PK ํ๋
@GeneratedValue: PK์ ์์ฑ ๊ท์น์ ๋ช ์
@Column: ํ ์ด๋ธ์ ์ปฌ๋ผ์ ๊ธฐ๋ณธ๊ฐ ์ธ์ ์ถ๊ฐ๋ก ๋ณ๊ฒฝ ํ์ํ ์ต์ ์์๋๋ง ์ฌ์ฉํ๋ฉด ๋จ
@Builder
- ํด๋น ํด๋์ค์ ๋น๋ ํจํด ํด๋์ค ์์ฑ
- ์์ฑ์ ์๋จ์ ์ ์ธ ์ ์์ฑ์์ ํฌํจ๋ ํ๋๋ง ๋น๋์ ํฌํจ
- ๋น๋๋ฅผ ํตํด ์ต์ข ๊ฐ์ ์ฑ์ด ํ DB์ ๊ฐ์ insertํ๊ฒ ๋จ
๐ก ๋น๋ vs ์์ฑ์
๋น๋๋ ์ง๊ธ ์ฑ์์ผ ํ ํ๋๊ฐ ๋ฌด์์ธ์ง ์ง์ ํ ์ ์์ด ์์ฑ์๋ณด๋ค ๋ช ํํ๋ค๋ ์ฅ์ ์ด ์๋ค
ex) ๋น๋๋ a(a).b(b).build(); ๋ก ํํํ๋ ๋ฐ๋ฉด ์์ฑ์๋ new (a,b);๋ก ํํ๋จ
3. Repository ์ธํฐํ์ด์ค
- MyBatis ๋ฑ์์ Dao๋ผ๊ณ ๋ถ๋ฆฌ๋ DB Layer ์ ๊ทผ์๋ฅผ JPA์์๋ Repository๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ ์ธํฐํ์ด์ค๋ก ์์ฑํจ
- Entity ํด๋์ค์ ๊ธฐ๋ณธ Entity Repository๋ ๊ฐ์ ๋๋ฉ์ธ ํจํค์ง์์ ํจ๊ป ๊ด๋ฆฌํด์ผ ํจ
- JpaRepository<Entityํด๋์ค, PKํ์ > ์ ์์ํ๋ฉด ๊ธฐ๋ณธ์ ์ธ CRUD ๋ฉ์๋๊ฐ ์๋ ์์ฑ๋จ
4. Repository ํ ์คํธ
package com.oliviarla.springboot.web.domain.posts;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PostRepositoryTest {
@Autowired
PostsRepository postsRepository;
@After //ํ
์คํธ์ฉ DB์ธ H2์ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ์ญ์ ํด ํ
์คํธ ๊ฐ ๋ฐ์ดํฐ ์นจ๋ฒ์ ๋ง๊ธฐ ์ํด ์ฌ์ฉ
public void cleanup(){
postsRepository.deleteAll();
}
@Test
public void load_post(){
//given
String title="ํ
์คํธ ๊ฒ์๊ธ";
String content="ํ
์คํธ ๋ณธ๋ฌธ";
// insert/update ์ฟผ๋ฆฌ ์คํ
postsRepository.save(Posts.builder()
.title(title)
.content(content)
.author("me")
.build());
//when
List<Posts> postsList=postsRepository.findAll(); //ํ
์ด๋ธ์ ๋ชจ๋ ๋ฐ์ดํฐ ์กฐํ
//then
Posts posts = postsList.get(0);
assertThat(posts.getTitle()).isEqualTo(title);
assertThat(posts.getContent()).isEqualTo(content);
}
}
๐ก ์ฝ์์์ ์ค์ ์คํ๋ ์ฟผ๋ฆฌ๋ฅผ MySQL ๋ฒ์ ผ์ผ๋ก ํ์ธํ๋ ๋ฐฉ๋ฒ
application.properties์ ๋ค์ ์ฝ๋ ์ถ๊ฐ
spring.jpa.show_sql = true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
'Spring Boot > ์คํ๋ง ๋ถํธ์ AWS๋ก ํผ์ ๊ตฌํํ๋ ์น ์๋น์ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
6์ฅ: AWS ์๋ฒ ํ๊ฒฝ ๋ง๋ค๊ธฐ (0) | 2022.06.27 |
---|---|
3์ฅ: JPA๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ค๋ฃจ๊ธฐ (2) (0) | 2022.06.15 |
2์ฅ: ํ ์คํธ ์ฝ๋ ์์ฑํ๊ธฐ (0) | 2022.06.13 |
1์ฅ: ์ธํ ๋ฆฌ์ ์ด ์ฌ์ฉํ๊ธฐ (์์ ์ค) (0) | 2022.06.13 |
๋๊ธ