✅ 1. Spring Data JPA란?
Spring Data JPA는 Spring에서 JPA(Java Persistence API)를 더 쉽게 사용할 수 있도록 도와주는 모듈이야.
복잡한 SQL 없이 인터페이스만 정의하면 자동으로 구현해주는 기능을 제공해, 개발자가 비즈니스 로직에 집중할 수 있게 해줘.
핵심 키워드 요약:
- JPA: 자바 ORM 기술 표준 (ORM이 뭐냐고? → 2번에서 설명해!)
- Spring Data JPA: JPA를 더 쉽게 쓰게 도와주는 스프링 기술
- 목표: 반복적인 코드 제거, 개발 생산성 향상
✅ 2. ORM(Object Relational Mapping)이란?
ORM은 **객체(Object)와 관계형 데이터베이스(Relational DB)를 연결(Mapping)**해주는 기술이야.
즉, Java 객체 <-> DB 테이블을 자동으로 매핑해주는 거지.
예를 들어, 아래처럼 User 클래스가 있으면:
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
}
JPA는 이걸 보고 자동으로 user 테이블을 생성하고, insert, select, update, delete 등의 SQL을 만들어줘!
✅ 3. JPA와 JDBC의 차이
구분 | JDBC | JPA(Spring Data JPA)포함 |
SQL 작성 | 직접 SQL 작성 필요 | 자동으로 SQL 생성 |
반복 코드 | 많음 (Connection, Statement 등) | 거의 없음 |
유지보수 | 어렵고 불안정 | 객체지향적이고 가독성 ↑ |
생산성 | 낮음 | 매우 높음 |
학습 난이도 | 낮음 | 처음엔 조금 어려움 (하지만 금방 적응됨!) |
✅ 4. Spring Data JPA의 주요 특징
- 인터페이스만 작성하면 구현은 자동!
- 쿼리 메서드 자동 생성 (findByName, findByEmailAndStatus 등)
- 페이징, 정렬 지원
- JPQL, Native SQL도 필요 시 사용 가능
- 다양한 확장성 (QueryDSL, Specification 등)
✅ 5. 기본 설정 방법
1.build.gradle에 의존성 추가 (Spring Boot 기준)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2' // 테스트용 내장 DB
}
2. application.yml 설정
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
3.엔티티 클래스 생성
@Entity
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
private String content;
}
public interface PostRepository extends JpaRepository<Post, Long> {
List<Post> findByTitle(String title);
}
@Service
public class PostService {
private final PostRepository postRepository;
public PostService(PostRepository postRepository) {
this.postRepository = postRepository;
}
public List<Post> getPostsByTitle(String title) {
return postRepository.findByTitle(title);
}
}
✅ 6. 주요 기능 정리
기능 | 예시 코드 | 설명 |
전체 조회 | findAll() | 모든 데이터 가져오기 |
ID로 조회 | findById(id) | 특정 ID의 데이터 가져오기 |
저장 | save(post) | 새로운 데이터 저장 or 수정 |
삭제 | delete(post) | 데이터 삭제 |
조건 검색 | findByTitle(String title) | 메서드 이름으로 쿼리 자동 생성 |
페이징 처리 | findAll(Pageable pageable) | 페이지별로 데이터 조회 |
정렬 | findAll(Sort.by("title").descending()) | 정렬 조건 추가 |
✅ 7. Spring Data JPA 사용 시 주의사항
- 객체 간 관계(연관관계 매핑) 설정이 중요 (예: @OneToMany, @ManyToOne)
- 무분별한 fetch = EAGER 사용은 성능 저하의 원인
- 복잡한 쿼리는 JPQL 또는 QueryDSL 사용이 좋음
- 너무 많은 로직을 Repository에 넣지 말 것 → Service에 분리
✅ 8. 요약
💡 Spring Data JPA = JPA + Spring + 자동화 마법
→ 반복적인 SQL 작성 없이 인터페이스만으로 DB를 다룰 수 있어!
1. 예제 프로젝트 구조
먼저, 우리가 사용할 예제는 블로그 시스템이라고 가정해볼게. 이 시스템에서는 Post라는 게시물을 다루게 되며, 이를 위해 Spring Data JPA와 함께 필요한 폴더 구조를 설계할 거야.
프로젝트 구조
spring-data-jpa-example/
│
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── blog/
│ │ │ ├── BlogApplication.java // Spring Boot 메인 애플리케이션
│ │ │ ├── controller/
│ │ │ │ └── PostController.java // 사용자 요청을 처리하는 컨트롤러
│ │ │ ├── model/
│ │ │ │ └── Post.java // 게시물 엔티티 클래스
│ │ │ ├── repository/
│ │ │ │ └── PostRepository.java // 데이터베이스 처리
│ │ │ ├── service/
│ │ │ │ └── PostService.java // 비즈니스 로직 처리
│ │ │ └── BlogApplication.java // Spring Boot 애플리케이션 시작점
│ │ └── resources/
│ │ ├── application.yml // 데이터베이스 설정
│ │ └── templates/
│ │ └── post-list.html // Thymeleaf 템플릿
└── build.gradle // Gradle 빌드 설정
2. 실습 샘플
1️⃣ Post 엔티티 클래스 (model/Post.java)
우선, Post라는 게시물 엔티티 클래스를 만들자. 이 클래스는 JPA가 자동으로 DB 테이블과 매핑할 객체지향적 모델이야.
package com.example.blog.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Data;
@Entity // JPA 엔티티
@Data // Lombok으로 getter, setter 자동 생성
public class Post {
@Id
@GeneratedValue
private Long id; // 게시물 ID (Primary Key)
private String title; // 게시물 제목
private String content; // 게시물 내용
private String author; // 게시물 작성자
}
2️⃣ Post Repository 인터페이스 (repository/PostRepository.java)
JPA는 JpaRepository를 상속받은 Repository 인터페이스를 통해 CRUD 작업을 자동으로 해준다. 여기서 PostRepository는 데이터베이스에 저장된 Post 객체를 다룬다.
package com.example.blog.repository;
import com.example.blog.model.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface PostRepository extends JpaRepository<Post, Long> {
// 제목으로 게시물 찾기
List<Post> findByTitle(String title);
}
3️⃣ PostService 서비스 클래스 (service/PostService.java)
서비스 클래스에서는 비즈니스 로직을 처리한다. 이곳에서 데이터를 Repository와 상호작용하여 가공하고, 컨트롤러로 전달한다.
package com.example.blog.service;
import com.example.blog.model.Post;
import com.example.blog.repository.PostRepository;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PostService {
private final PostRepository postRepository;
public PostService(PostRepository postRepository) {
this.postRepository = postRepository;
}
// 제목으로 게시물 조회
public List<Post> getPostsByTitle(String title) {
return postRepository.findByTitle(title);
}
// 모든 게시물 조회
public List<Post> getAllPosts() {
return postRepository.findAll();
}
// 게시물 저장
public Post savePost(Post post) {
return postRepository.save(post);
}
}
4️⃣ PostController 컨트롤러 클래스 (controller/PostController.java)
컨트롤러는 사용자로부터 요청을 받고, 그에 대한 응답을 반환하는 역할을 한다. PostController는 사용자로부터의 요청을 처리하고, 그에 맞는 데이터를 PostService로 전달하여 최종적으로 HTML 템플릿을 렌더링하거나 JSON 응답을 반환한다.
package com.example.blog.controller;
import com.example.blog.model.Post;
import com.example.blog.service.PostService;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.stereotype.Controller;
@Controller
public class PostController {
private final PostService postService;
public PostController(PostService postService) {
this.postService = postService;
}
// 모든 게시물 리스트 보여주기
@GetMapping("/posts")
public String getAllPosts(Model model) {
model.addAttribute("posts", postService.getAllPosts());
return "post-list"; // Thymeleaf 템플릿을 사용하여 HTML을 반환
}
// 제목으로 게시물 찾기
@GetMapping("/posts/search")
public String getPostsByTitle(@RequestParam String title, Model model) {
model.addAttribute("posts", postService.getPostsByTitle(title));
return "post-list";
}
// 게시물 추가 페이지
@GetMapping("/posts/new")
public String createPostForm(Model model) {
model.addAttribute("post", new Post());
return "post-form"; // 게시물 작성 폼 페이지
}
// 게시물 저장
@PostMapping("/posts")
public String createPost(@ModelAttribute Post post) {
postService.savePost(post);
return "redirect:/posts"; // 게시물 목록 페이지로 리다이렉트
}
}
5️⃣ HTML 템플릿 (templates/post-list.html)
Thymeleaf를 사용하여 HTML 템플릿을 만들어서 데이터가 어떻게 화면에 출력될지 정의한다. 예를 들어, 게시물 목록을 출력하는 post-list.html 템플릿을 만들어보자.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>게시물 목록</title>
</head>
<body>
<h1>게시물 목록</h1>
<form action="/posts/search" method="get">
<input type="text" name="title" placeholder="검색할 제목 입력">
<button type="submit">검색</button>
</form>
<ul>
<li th:each="post : ${posts}">
<h2 th:text="${post.title}"></h2>
<p th:text="${post.content}"></p>
<p><strong th:text="${post.author}"></strong></p>
</li>
</ul>
</body>
</html>
6️⃣ application.yml 설정 (resources/application.yml)
데이터베이스 연결 설정은 application.yml에 설정할 수 있다. 여기서는 H2 데이터베이스를 예시로 사용할 것이다.
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password: password
jpa:
hibernate:
ddl-auto: update # 애플리케이션 시작 시 테이블 자동 생성
show-sql: true # SQL 쿼리 출력
properties:
hibernate:
format_sql: true
3. 실행 방법
- 프로젝트 빌드
- Gradle을 사용하고 있으므로 ./gradlew build 명령어로 프로젝트를 빌드할 수 있다.
- 애플리케이션 실행
- BlogApplication.java 파일을 실행하여 애플리케이션을 시작할 수 있다.
- 실행 후 http://localhost:8080/posts로 접속하면 게시물 목록을 확인할 수 있다.
4. 결론
이제 Spring Data JPA와 함께하는 기본적인 CRUD 애플리케이션을 구현했어.
이 예제를 기반으로 더 복잡한 비즈니스 로직이나 다양한 데이터 처리가 필요한 상황에 맞게 확장할 수 있어.
- PostRepository는 데이터베이스와 직접 상호작용하는 부분
- PostService는 비즈니스 로직을 처리하는 곳
- PostController는 사용자 요청을 받아서 응답하는 부분
- Thymeleaf 템플릿은 사용자에게 보여줄 HTML을 생성
이와 같은 구조로 애플리케이션을 구현해보면 Spring Data JPA의 장점을 체감할 수 있을 거야!
'프로그래밍 > Spring' 카테고리의 다른 글
ORM이란? (0) | 2025.04.04 |
---|---|
JDBC란? (0) | 2025.04.04 |
REST API란? (0) | 2025.04.04 |
http응답 상태 코드 참조 사이트 (0) | 2025.04.03 |
@Controller와 @RestController의 차이 (0) | 2025.04.02 |