728x90

✅ 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;
}

 
4.Repository 생성 (인터페이스만)
public interface PostRepository extends JpaRepository<Post, Long> {
    List<Post> findByTitle(String title);
}
 
 
 
5.서비스에서 사용하기
 
@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. 실행 방법

  1. 프로젝트 빌드
    • Gradle을 사용하고 있으므로 ./gradlew build 명령어로 프로젝트를 빌드할 수 있다.
  2. 애플리케이션 실행
    • BlogApplication.java 파일을 실행하여 애플리케이션을 시작할 수 있다.
    • 실행 후 http://localhost:8080/posts로 접속하면 게시물 목록을 확인할 수 있다.

 

 


4. 결론

이제 Spring Data JPA와 함께하는 기본적인 CRUD 애플리케이션을 구현했어.
이 예제를 기반으로 더 복잡한 비즈니스 로직이나 다양한 데이터 처리가 필요한 상황에 맞게 확장할 수 있어.

  • PostRepository는 데이터베이스와 직접 상호작용하는 부분
  • PostService는 비즈니스 로직을 처리하는 곳
  • PostController는 사용자 요청을 받아서 응답하는 부분
  • Thymeleaf 템플릿은 사용자에게 보여줄 HTML을 생성

이와 같은 구조로 애플리케이션을 구현해보면 Spring Data JPA의 장점을 체감할 수 있을 거야!

728x90

'프로그래밍 > 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