Spring Boot

[Spring Boot] JpaRepository 개념, 사용 방법 (쿼리 메서드, @Query, JPQL, Native Query)

공대생안씨 2024. 9. 5. 20:54

1. JpaRepository 란 ?

  • Spring Data JPA 에서 제공하는 DB접근을 위한 인터페이스
  • JPA 기반으로 DB와의 상호작용을 간편하게 해줌
    • CRUD 작업을 수행하는 메서드를 기본 제공
    • 개발자가 직접 구현할 필요 x !

 

2. JpaRepository 사용 방법

2-1. 라이브러리 추가

  • build.gradle
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

 

2-2. Repository 작성

  • JpaRepository를 상속받음
  • JpaRepository<엔티티 클래스, 엔티티의 ID 타입>
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    
}

// 예시 엔티티 User
@Entity
public class User {
		
	@Id
	private Long id;
		
	// 기타 필드 작성
}
📌 @Repository, @Transactional 추가 관련

- @Repository
        - JpaRepository를 상속받은 인터페이스는 Spring Data JPA에 의해 자동으로 빈 등록이 됨
        - 따라서 @Repository 를 추가하지 않아도 됨
        - 그러나 사용자 정의 메서드를 포함하는 경우에는 명시적으로 @Repository 를 추가하는 것이 좋음
- @Transactional
        - JpaRepository의 기본 메서드(save, delete)는 트랜잭션 처리를 자동으로 지원
        - 그러나 여러 작업을 묶어서 처리해야 하는 경우는 @Transactional 추가하는 것이 좋음

 

2-3. JpaRepository → 기본 제공 메서드

(가장 기본적인 메서드 몇개)

  • save(S entity) : 엔티티 저장
    • 엔티티의 id가 이미 존재한다면 update 진행
  • findById(ID id) : 해당 id 에 해당하는 엔티티 조회
  • findAll() : 모든 엔티티 조회
  • deleteById(ID id) : 해당 id 에 해당하는 엔티티 삭제
  • count() : 엔티티 개수 반환
  • existsById(ID id) : 해당 id 에 해당하는 엔티티 존재 여부 확인
  • 등등 …

 

2-4. 커스텀 쿼리 메서드

  • 메서드 이름을 기반으로 자동으로 쿼리 생성
  • 접두사 사용하는 형식으로 작성
    • findBy
    • deleteBy
    • And / Or
    • Like / NotLike
    • IsNull / IsNotNull
    • LessThan / GreaterThan
    • Between
    • OrderBy
    • countBy
public interface UserRepository extends JpaRepository<User, Long> {
    
    // 커스텀 쿼리 메서드
    User findByEmail(String email);  // email을 갖는 User 반환
    
    Long countByEmail(String email);  // email을 갖는 User 엔티티 수 반환
    
    boolean existsByEmail(String email);  // email을 갖는 User 엔티티 존재 여부 반환
    
    List<User> findByAgeGraterThan(int age); // age보다 나이 많은 User 반환
    List<User> findByName(String name);  // 이름이 name인 User 반환
    List<User> findByNameContaining(String name);  // 이름에 name 포함하는 User 반환
	  List<User> findByAgeAndEmail(int age, String email); // 나이가 age이고 email이 동일한 User 반환
	  
	  void deleteByAge(int age);  // 나이가 age인 User 삭제
}
📌  - findBy, findAllBy : 기능적으로 차이 x
      - 리턴 타입으로 구분함! ⇒ 단일 엔티티 리턴 or 리스트 리턴으로 구분

 

2-5. @Query

  • 복잡한 쿼리 작성 가능, 성능 최적화에 유용함

2-5-1. JPQL

public interface UserRepository extends JpaRepository<User, Long> {

    @Query("SELECT u FROM User u WHERE u.age > :age")
    List<User> findUsersOlderThan(@Param("age") int age);
    
    @Query("SELECT u FROM User u WHERE email = ?1")
    User findByEmail(String email);
}

2-5-2. Native Query

  • SQL 쿼리 직접 사용
  • nativeQuery 속성 → true로 설정
public interface UserRepository extends JpaRepository<User, Long> {

	@Query("SELECT * FROM User u WHERE email = ?1", nativeQuery=true)
	User findByEmail(String email);
		
	@Query("SELECT * FROM User u WHERE u.status = :status AND u.name = :name", nativeQuery=true)
	User findUserByStatusAndNameNamedParamsNative(@Param("status") Integer status, @Param("name") String name);
}