# **데이터 처리와 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` 어노테이션을 사용하여 **클래스를 데이터베이스 테이블과 매핑**합니다. ```java 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 JPA**의 `JpaRepository` 인터페이스를 사용하면, 기본적인 CRUD 기능을 자동으로 구현할 수 있습니다. ```java import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository { // 기본 CRUD 기능 제공 } ``` ✔ **`JpaRepository`**: `User` 엔티티를 관리하며, 기본 키 타입은 `Long` ✔ `findById(id)`, `save(entity)`, `deleteById(id)` 등 기본적인 데이터 처리 메서드 제공 --- ### **📌 3) Service (비즈니스 로직 계층)** 데이터 처리 로직을 서비스 계층에서 구현하여 컨트롤러와 분리합니다. ```java 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 getAllUsers() { return userRepository.findAll(); } } ``` ✔ **서비스 계층을 사용하여 비즈니스 로직을 분리** ✔ **`@Transactional`을 사용하여 트랜잭션 관리** --- ### **📌 4) Controller (요청 처리 계층)** 사용자의 요청을 받아 서비스 계층을 호출하고 응답을 반환합니다. ```java 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 createUser(@RequestParam String name, @RequestParam int age) { return ResponseEntity.ok(userService.createUser(name, age)); } @GetMapping public ResponseEntity> 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**을 사용하여 객체 중심의 쿼리를 작성할 수 있습니다. ```java import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; public interface UserRepository extends JpaRepository { // 이름으로 사용자 찾기 @Query("SELECT u FROM User u WHERE u.name = :name") List findByName(@Param("name") String name); } ``` ✔ SQL과 유사하지만, **테이블명이 아니라 엔티티 클래스명을 사용** --- ### **📌 2) Native Query (SQL 직접 사용)** 기본 SQL 쿼리를 직접 사용할 수도 있습니다. ```java @Query(value = "SELECT * FROM users WHERE age >= :age", nativeQuery = true) List findUsersByAge(@Param("age") int age); ``` ✔ 복잡한 SQL 쿼리를 그대로 활용 가능 --- ## **5. JPA의 장점과 단점** ### **📌 JPA의 장점** ✔ **SQL을 직접 작성할 필요 없음** → 생산성 증가 ✔ **객체지향적인 데이터 처리 가능** → 코드의 가독성과 유지보수성 향상 ✔ **트랜잭션 관리가 용이함** ✔ **캐싱 및 성능 최적화 기능 제공** ### **📌 JPA의 단점** ❌ 초기 학습 비용이 존재 ❌ 복잡한 SQL 튜닝이 필요한 경우 SQL보다 불리할 수 있음 ❌ 데이터베이스 변경 시, 마이그레이션이 필요 --- ## **6. 정리** ✔ **JPA는 객체지향 방식으로 데이터를 처리하는 ORM 기술** ✔ **Entity, Repository, Service, Controller 구조로 데이터 처리를 설계** ✔ **JPQL 및 Native Query를 활용하여 데이터 조회 가능** ✔ **트랜잭션을 활용하여 데이터 일관성을 유지** JPA를 활용하면 **효율적인 데이터 처리와 유지보수성 높은 애플리케이션을 만들 수 있습니다!**