Spring Data JPA 이해하기: 주요 구성 요소와 어노테이션

2024. 7. 19. 15:22·개발 노트/Spring

Spring Data JPA 개요 및 사용 방법

Spring Data JPA란?

Spring Data JPA는 Spring 프레임워크의 일부로, JPA(Java Persistence API)를 쉽게 사용할 수 있도록 도와주는 라이브러리이다. Spring Data JPA는 리포지토리 추상화(Repository Abstraction)를 제공하여, 개발자가 데이터 접근 계층을 더욱 간편하게 구현할 수 있도록 돕는다. 이를 통해 반복적인 CRUD (Create, Read, Update, Delete) 작업을 줄이고, 복잡한 쿼리 작성도 손쉽게 할 수 있다.

 

왜 Spring Data JPA를 사용하는가?

Spring Data JPA를 사용하는 이유는 다음과 같다:

  1. 생산성 향상: 반복적인 CRUD 작업을 자동화하여 개발 생산성을 높인다.
  2. 코드의 간결성: 데이터 접근 계층의 코드를 간결하고 명확하게 작성할 수 있다.
  3. 유연성: 커스텀 쿼리와 동적 쿼리를 쉽게 작성할 수 있다.
  4. 통합성: 스프링 프레임워크와의 자연스러운 통합을 제공하여 전체 애플리케이션 구조를 단순화한다.
  5. 테스트 용이성: Spring Data JPA는 Mocking 프레임워크와 함께 사용하여 단위 테스트와 통합 테스트를 쉽게 작성할 수 있다.

 

Spring Data JPA의 주요 구성 요소

Spring Data JPA는 몇 가지 주요 구성 요소로 이루어져 있다:

1. Repository 인터페이스

Spring Data JPA는 Repository 인터페이스를 통해 데이터 접근 계층을 추상화한다. 기본적으로 JpaRepository 인터페이스를 확장하여 사용할 수 있다.

예시 코드
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByUsername(String username);
}
  • JpaRepository: 기본적인 CRUD 및 페이징, 소팅 기능을 제공하는 인터페이스.
  • findByUsername: 메소드 이름을 기반으로 쿼리를 자동 생성한다.

2. @Query 어노테이션

복잡한 쿼리를 작성할 때는 @Query 어노테이션을 사용하여 직접 JPQL 또는 네이티브 SQL 쿼리를 작성할 수 있다.

예시 코드
public interface UserRepository extends JpaRepository<User, Long> {
    @Query("SELECT u FROM User u WHERE u.email = :email")
    User findByEmail(@Param("email") String email);
}
  • @Query: 직접 쿼리를 작성할 수 있는 어노테이션.
  • @Param: 쿼리 매개변수를 설정하는 어노테이션.

3. 페이징 및 소팅

Spring Data JPA는 페이징 및 소팅 기능을 통해 대량의 데이터를 효율적으로 처리할 수 있다.

예시 코드
public interface UserRepository extends JpaRepository<User, Long> {
    Page<User> findByActive(boolean active, Pageable pageable);
}
  • Pageable: 페이징 및 소팅 정보를 제공하는 인터페이스.
  • Page: 페이징 결과를 담는 객체.

4. Specification

복잡한 동적 쿼리를 작성할 때는 Specification을 사용하여 동적 쿼리를 구성할 수 있다.

예시 코드
public class UserSpecification implements Specification<User> {
    private String username;

    public UserSpecification(String username) {
        this.username = username;
    }

    @Override
    public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
        return criteriaBuilder.equal(root.get("username"), this.username);
    }
}
  • Specification: 동적 쿼리를 작성하기 위한 인터페이스.
  • Predicate: 조건을 정의하는 객체.

 

Spring Data JPA의 어노테이션 종류

Spring Data JPA에서 자주 사용되는 어노테이션들은 다음과 같다:

1. @Entity

@Entity는 JPA에서 해당 클래스가 데이터베이스 테이블과 매핑됨을 나타내는 어노테이션이다.

@Entity
public class User {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    // getter와 setter
}

2. @Id

@Id는 엔티티의 기본 키를 지정하는 어노테이션이다.

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // ...
}

3. @GeneratedValue

@GeneratedValue는 기본 키 생성 전략을 지정하는 어노테이션이다.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

4. @Query

@Query는 JPQL 또는 네이티브 SQL 쿼리를 직접 작성할 수 있도록 하는 어노테이션이다.

@Query("SELECT u FROM User u WHERE u.email = :email")
User findByEmail(@Param("email") String email);

5. @Modifying

@Modifying은 데이터베이스에 변경 작업(INSERT, UPDATE, DELETE)을 수행하는 쿼리를 지정할 때 사용하는 어노테이션이다.

@Modifying
@Query("UPDATE User u SET u.active = false WHERE u.lastLogin < :date")
int deactivateInactiveUsers(@Param("date") LocalDate date);

6. @Transactional

@Transactional은 메소드 또는 클래스에 트랜잭션을 적용하는 어노테이션이다. 트랜잭션 관리에 사용된다. 자세한 내용은 다음 포스팅에서 다룰 예정이다.

@Transactional
public void saveUser(User user) {
    userRepository.save(user);
}

7. @Repository

@Repository는 데이터 접근 계층의 클래스임을 나타내는 어노테이션이다. Spring에서 예외를 일관되게 변환하는 역할도 한다.

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    // ...
}

 

 

Spring Data JPA의 동작 원리

Spring Data JPA는 개발자가 정의한 리포지토리 인터페이스를 기반으로 프록시 객체를 생성하여 데이터베이스 작업을 수행한다. 이 과정에서 스프링은 해당 인터페이스의 구현체를 자동으로 생성하고, 필요한 곳에 주입한다.

동작 과정

  1. 리포지토리 인터페이스 정의: JpaRepository 또는 CrudRepository를 확장한 인터페이스를 정의한다.
  2. 스프링 컨테이너가 프록시 객체 생성: 스프링 컨테이너가 런타임 시 해당 인터페이스의 프록시 객체를 생성한다.
  3. 의존성 주입: 생성된 프록시 객체가 서비스 클래스 등에 주입된다.
  4. 데이터베이스 작업 수행: 프록시 객체가 데이터베이스와의 상호작용을 처리한다.

 

생성자 주입

Spring에서는 @Autowired 어노테이션을 사용한 필드 주입보다는 생성자 주입을 권장한다. 생성자 주입은 테스트 용이성과 의존성 주입의 명시성을 높이는 데 도움이 된다.

예시 코드

@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User saveUser(User user) {
        return userRepository.save(user);
    }

    public User findUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

 

마무리

Spring Data JPA는 JPA를 더욱 쉽게 사용할 수 있도록 도와주는 강력한 도구이다. 기본적인 CRUD 기능부터 페이징, 소팅, 커스텀 쿼리, 동적 쿼리 등 다양한 기능을 통해 개발 생산성을 높이고 코드의 유지보수성을 향상시킨다. Spring Data JPA를 잘 활용하면 데이터 접근 계층을 효율적으로 관리할 수 있다.

'개발 노트 > Spring' 카테고리의 다른 글

JPA에서 N+1 문제  (2) 2024.07.19
JPA에서 트랜잭션 처리 및 데이터베이스 격리 수준  (0) 2024.07.19
JPA 이해하기: 동작 원리와 핵심 구성 요소  (0) 2024.07.19
'개발 노트/Spring' 카테고리의 다른 글
  • JPA에서 N+1 문제
  • JPA에서 트랜잭션 처리 및 데이터베이스 격리 수준
  • JPA 이해하기: 동작 원리와 핵심 구성 요소
악덕
악덕
우당탕탕 개발 블로그
  • 악덕
    버그와 함께 춤을
    악덕
  • 전체
    오늘
    어제
    • 전체 (26)
      • TIL (2)
      • 개발 노트 (19)
        • Java (5)
        • JavaScript (1)
        • Spring (4)
        • Linux (1)
        • DevOps (1)
        • etc. (7)
      • 문제 풀이 (0)
      • 삽질 로그 (3)
      • 기타 (2)
  • 링크

    • GitHub
    • Project.zip
    • 밀로(millo)
  • 태그

    gdg
    자료형
    프로그래밍언어
    springboot
    OOP
    mysql
    컨테이너
    java
    웹개발
    Docker
    프로그래밍
    객체지향 프로그래밍
    java persistence api
    자바기초
    solid 원칙
    Spring Data JPA
    JPA
    ssl
    Til
    DevOps
  • hELLO· Designed By정상우.v4.10.3
악덕
Spring Data JPA 이해하기: 주요 구성 요소와 어노테이션
상단으로

티스토리툴바