Spring Boot์ JPA๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋ํ๊ธฐ: ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๊ฐ์ด๋
Spring Boot ์ JPA(Java Persistence API) ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋ ์ด ๊ฐํธํด์ง๋๋ค. JPA๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด(Java)์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(RDB)๋ฅผ ๋งคํํด์ฃผ๋ ORM(Object Relational Mapping) ๊ธฐ์ ์ ๋๋ค. ์ด ๊ธ์์๋ Spring Data JPA ๊ธฐ๋ณธ ์ค์ , Entity์ Repository ์ค๊ณ , ๊ทธ๋ฆฌ๊ณ Query Method์ JPQL ํ์ฉ๋ฒ ์ ์ฝ๊ฒ ์ค๋ช ํฉ๋๋ค.
๋ชฉ์ฐจ
- Spring Data JPA๋ ๋ฌด์์ธ๊ฐ?
- Spring Boot์ JPA ์ฐ๋ ์ค์ ํ๊ธฐ
- Entity์ Repository ์ค๊ณ ๋ฐฉ๋ฒ
- Query Method์ JPQL ํ์ฉํ๊ธฐ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋์ ๋ํ ํธ๋ ๋์ ์ค์์ฑ
1. Spring Data JPA๋ ๋ฌด์์ธ๊ฐ?
Spring Data JPA ๋ JPA๋ฅผ ๊ฐํธํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ๋๋ ์คํ๋ง ํ๋ก์ ํธ ์ ๋๋ค. JPA๋ SQL ๋์ ์๋ฐ ๊ฐ์ฒด๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์กฐ์ ํ ์ ์๊ฒ ํ๋ฉฐ, Spring Data JPA๋ ์ด๋ฌํ ๊ธฐ๋ฅ์ ๋ ์ฝ๊ฒ ํ์ฉํ ์ ์๋๋ก ์๋ํ๋ Repository ์์ฑ ์ ์ง์ํฉ๋๋ค.
Spring Data JPA์ ์ฃผ์ ๊ธฐ๋ฅ
- ์๋ Repository ์์ฑ : ๊ธฐ๋ณธ์ ์ธ CRUD(Create, Read, Update, Delete) ๊ธฐ๋ฅ ์ ๊ณต
- Query Method : ๋ฉ์๋ ์ด๋ฆ๋ง์ผ๋ก SQL ์ฟผ๋ฆฌ ์์ฑ
- JPQL(Java Persistence Query Language) : ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑ
์ด์ JPA์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฐ๋ํ๋ ๋ฐฉ๋ฒ์ ์ฝ๋์ ํจ๊ป ์์๋ณด๊ฒ ์ต๋๋ค.
2. Spring Boot์ JPA ์ฐ๋ ์ค์ ํ๊ธฐ
์์กด์ฑ ์ถ๊ฐ (pom.xml)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
-
spring-boot-starter-data-jpa
: JPA ๊ด๋ จ ๊ธฐ๋ฅ ์ ๊ณต - H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค : ํ ์คํธ์ฉ์ผ๋ก ๊ฐ๋ฒผ์ด ์ธ๋ฉ๋ชจ๋ฆฌ DB ์ฌ์ฉ
์ค์ ํ์ผ ์์ฑ (application.properties)
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
์ด ์ค์ ์ H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ๊ฒฐ ์ ์ค์ ํ๋ฉฐ, ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์ SQL ๋ก๊ทธ๋ฅผ ์ฝ์์ ์ถ๋ ฅ ํฉ๋๋ค.
3. Entity์ Repository ์ค๊ณ ๋ฐฉ๋ฒ
Entity ํด๋์ค ์์ฑ: User.java
package com.example.demo.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
public User(String name, String email) {
this.name = name;
this.email = email;
}
}
-
@Entity
: ํด๋น ํด๋์ค๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๊ณผ ๋งคํ๋จ์ ๋ํ๋ ๋๋ค. -
@Id
: ๊ธฐ๋ณธ ํค ํ๋๋ฅผ ์ง์ ํฉ๋๋ค. -
@GeneratedValue
: ๊ธฐ๋ณธ ํค ์์ฑ ์ ๋ต์ ์ง์ ํฉ๋๋ค.
Repository ์ธํฐํ์ด์ค ์์ฑ: UserRepository.java
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
-
JpaRepository
: ๊ธฐ๋ณธ์ ์ธ CRUD ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ์ ๊ณตํฉ๋๋ค. - ์ด Repository๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉ ํ ์ ์์ต๋๋ค.
4. Query Method์ JPQL ํ์ฉํ๊ธฐ
Query Method ์ฌ์ฉ ์์
List<User> findByName(String name);
- ๋ฉ์๋ ์ด๋ฆ๋ง์ผ๋ก SQL ์ฟผ๋ฆฌ ๊ฐ ์๋ ์์ฑ๋ฉ๋๋ค.
-
findByName
:SELECT * FROM user WHERE name = ?
์ฟผ๋ฆฌ์ ๋์ผํฉ๋๋ค.
JPQL ์ฌ์ฉ ์์ : UserService.java
package com.example.demo.service;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> findAllUsers() {
return userRepository.findAll();
}
public User saveUser(String name, String email) {
User user = new User(name, email);
return userRepository.save(user);
}
}
-
findAll()
: ๋ชจ๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค. -
save()
: ์๋ก์ด ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํฉ๋๋ค.
5. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋์ ๋ํ ํธ๋ ๋์ ์ค์์ฑ
- Spring Data JPA ๋ ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ ์ ๊ฐ์ ์ต์ ๊ฐ๋ฐ ํ๊ฒฝ์์ ํ์์ ์ธ ๊ธฐ์ ์ ๋๋ค.
- Statista ์ ์กฐ์ฌ์ ๋ฐ๋ฅด๋ฉด, ์ ์ธ๊ณ ๊ธฐ์ ์ 60% ์ด์ ์ด ๋ฐ์ดํฐ ์ค์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ JPA์ ORM์ ํ์ฉํ๊ณ ์์ต๋๋ค.
- ํนํ ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ JPA๋ฅผ ์ฌ์ฉํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ์๋ํ๋ Repository ์ฌ์ฉ์ด ์์ฐ์ฑ์ ํฌ๊ฒ ํฅ์ ์ํต๋๋ค.
๊ด๋ จ ๋งํฌ
Spring Data JPA ๋ ํผ๋ฐ์ค๐
H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณต์ ์ฌ์ดํธ๐
Java Persistence API(JPA) ๊ฐ์ด๋๐
FAQ
1. JPA์ MyBatis์ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ์?
- JPA๋ ๊ฐ์ฒด ์งํฅ ORM ๋ฐฉ์์ด๊ณ , MyBatis๋ SQL ๋งคํผ๋ก SQL ๋ฌธ์ ์ง์ ์์ฑํฉ๋๋ค.
2.
@Entity
์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ์ ๊ด๊ณ๋ ๋ฌด์์ธ๊ฐ์?
@Entity
๋ ์๋ฐ ํด๋์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ๋งคํํฉ๋๋ค. ํด๋์ค์ ํ๋๋ ํ ์ด๋ธ์ ์ปฌ๋ผ์ ๋์๋ฉ๋๋ค.
3. JPA์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ณ๊ฒฝ ์ ์๋์ผ๋ก ๋ฐ์๋๋์?
spring.jpa.hibernate.ddl-auto=update
์ค์ ์ ์ฌ์ฉํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์คํ๋ ๋ ์คํค๋ง๊ฐ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
4. JPQL๊ณผ SQL์ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ์?
- JPQL์ ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ์ฟผ๋ฆฌํ๋ ๋ฐ๋ฉด, SQL์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ๋์์ผ๋ก ์ฟผ๋ฆฌํฉ๋๋ค.
5. JPA ์ฑ๋ฅ ์ต์ ํ ๋ฐฉ๋ฒ์ ๋ฌด์์ธ๊ฐ์?
- Lazy Loading ๊ณผ ์บ์(Cache) ํ์ฉ ์ด ์ฑ๋ฅ ์ต์ ํ์ ๋์์ด ๋ฉ๋๋ค.
๋ง๋ฌด๋ฆฌ
์ด๋ฒ ํฌ์คํ ์์๋ Spring Boot์ JPA๋ฅผ ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์์ต๋๋ค. JPA๋ ์๋ฐ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ๋งคํ์ ๊ฐํธํ๊ฒ ์ฒ๋ฆฌํด์ฃผ๋ฉฐ, Spring Data JPA๋ ๊ธฐ๋ณธ์ ์ธ CRUD ๊ธฐ๋ฅ์ ์๋ํํ์ฌ ๊ฐ๋ฐ ์์ฐ์ฑ์ ํฌ๊ฒ ๋์ฌ์ค๋๋ค. ์ด ํฌ์คํ ์ ๋ฐํ์ผ๋ก ๋ ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ก์ง ๋ ์ง์ ๊ตฌํํด๋ณด์ธ์.
๊พธ์คํ ์ค์ต์ ํตํด JPA์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋์ ์์ ๊ฐ์ ๊ฐ๊ฒ ๋ ๊ฒ์ ๋๋ค!
๋๊ธ