Files
spring-boot-examples/docs/07_데이터 처리와 JPA.md
2025-04-08 19:56:24 +09:00

7.4 KiB

데이터 처리와 JPA

웹 애플리케이션에서 **데이터 처리(Data Processing)**는 필수적인 요소이며, 이를 효율적으로 다루기 위해 ORM 프레임워크인 **JPA (Java Persistence API)**가 널리 사용됩니다.
이번 글에서는 JPA의 기본 개념, 주요 기능, 실무 적용 방법을 살펴보겠습니다.


1. 데이터 처리란?

데이터 처리는 애플리케이션이 데이터를 **생성(Create), 읽기(Read), 수정(Update), 삭제(Delete)**하는 과정(CRUD)을 의미합니다.
Spring Boot에서는 JPA와 Spring Data JPA를 활용하여 효율적인 데이터 처리를 구현할 수 있습니다.

📌 전통적인 JDBC 방식과 JPA 방식 비교

방식 특징 코드 복잡도 유지보수성
JDBC (기본 SQL 사용) SQL 쿼리를 직접 작성 높음 낮음
JPA (ORM 방식) 객체 중심의 데이터 처리 낮음 높음

2. JPA란?

**JPA (Java Persistence API)**는 객체지향적인 방식으로 데이터베이스를 다룰 수 있도록 도와주는 ORM(Object-Relational Mapping) 기술입니다.
JPA를 사용하면 SQL을 직접 작성하지 않고, 엔티티(Entity) 객체를 이용하여 데이터베이스를 조작할 수 있습니다.

📌 JPA의 핵심 개념

  1. 엔티티(Entity): 데이터베이스 테이블과 매핑되는 클래스
  2. 리포지토리(Repository): 데이터 저장 및 조회를 담당하는 계층
  3. 트랜잭션(Transaction): 데이터 변경 작업을 하나의 단위로 처리
  4. JPQL(Java Persistence Query Language): 객체를 대상으로 하는 쿼리

3. JPA 실무 적용

📌 1) Entity (데이터 모델 정의)

JPA에서는 @Entity 어노테이션을 사용하여 클래스를 데이터베이스 테이블과 매핑합니다.

import jakarta.persistence.*;

@Entity  // User 엔티티는 DB의 users 테이블과 매핑됨
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 자동 증가 ID
    private Long id;

    @Column(nullable = false)  // name 컬럼은 null을 허용하지 않음
    private String name;

    @Column(nullable = false)
    private int age;

    public User() {}

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getter & Setter 생략
}

@Entity: 해당 클래스가 데이터베이스 테이블과 연결됨
@Table(name = "users"): 테이블명을 users로 지정
@Id: 기본 키(Primary Key) 설정
@GeneratedValue(strategy = GenerationType.IDENTITY): 자동 증가(AUTO_INCREMENT) 설정
@Column(nullable = false): null을 허용하지 않도록 설정


📌 2) Repository (데이터 접근 계층)

JPA에서는 Spring Data JPAJpaRepository 인터페이스를 사용하면, 기본적인 CRUD 기능을 자동으로 구현할 수 있습니다.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    // 기본 CRUD 기능 제공
}

JpaRepository<User, Long>: User 엔티티를 관리하며, 기본 키 타입은 Long
findById(id), save(entity), deleteById(id) 등 기본적인 데이터 처리 메서드 제공


📌 3) Service (비즈니스 로직 계층)

데이터 처리 로직을 서비스 계층에서 구현하여 컨트롤러와 분리합니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public User createUser(String name, int age) {
        if (age < 0) {
            throw new IllegalArgumentException("나이는 0 이상이어야 합니다.");
        }
        return userRepository.save(new User(name, age));
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

서비스 계층을 사용하여 비즈니스 로직을 분리
@Transactional을 사용하여 트랜잭션 관리


📌 4) Controller (요청 처리 계층)

사용자의 요청을 받아 서비스 계층을 호출하고 응답을 반환합니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<User> createUser(@RequestParam String name, @RequestParam int age) {
        return ResponseEntity.ok(userService.createUser(name, age));
    }

    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        return ResponseEntity.ok(userService.getAllUsers());
    }
}

@RestController: JSON 형식으로 데이터를 반환하는 컨트롤러
@RequestMapping("/users"): /users 경로의 API를 처리
@PostMapping: 새로운 사용자 생성
@GetMapping: 모든 사용자 조회


4. JPA에서 데이터 조회 (JPQL & Native Query)

📌 1) JPQL (Java Persistence Query Language)

JPA에서는 SQL 대신 JPQL을 사용하여 객체 중심의 쿼리를 작성할 수 있습니다.

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

    // 이름으로 사용자 찾기
    @Query("SELECT u FROM User u WHERE u.name = :name")
    List<User> findByName(@Param("name") String name);
}

✔ SQL과 유사하지만, 테이블명이 아니라 엔티티 클래스명을 사용


📌 2) Native Query (SQL 직접 사용)

기본 SQL 쿼리를 직접 사용할 수도 있습니다.

@Query(value = "SELECT * FROM users WHERE age >= :age", nativeQuery = true)
List<User> findUsersByAge(@Param("age") int age);

✔ 복잡한 SQL 쿼리를 그대로 활용 가능


5. JPA의 장점과 단점

📌 JPA의 장점

SQL을 직접 작성할 필요 없음 → 생산성 증가
객체지향적인 데이터 처리 가능 → 코드의 가독성과 유지보수성 향상
트랜잭션 관리가 용이함
캐싱 및 성능 최적화 기능 제공

📌 JPA의 단점

초기 학습 비용이 존재
복잡한 SQL 튜닝이 필요한 경우 SQL보다 불리할 수 있음
데이터베이스 변경 시, 마이그레이션이 필요


6. 정리

JPA는 객체지향 방식으로 데이터를 처리하는 ORM 기술
Entity, Repository, Service, Controller 구조로 데이터 처리를 설계
JPQL 및 Native Query를 활용하여 데이터 조회 가능
트랜잭션을 활용하여 데이터 일관성을 유지

JPA를 활용하면 효율적인 데이터 처리와 유지보수성 높은 애플리케이션을 만들 수 있습니다!