학습 목표
Spring Data JPA에서 제공하는 JPARepository의 개념과 그 활용을 알아 보자.
JPARepository란?
Spring Data JPA는 Repository 인터페이스를 통해 데이터 접근 계층을 간편하게 구현할 수 있도록 도와주는 프레임워크입니다. 개발자가 직접 DAO(Data Access Object) 클래스를 작성하지 않고도, JpaRepository를 상속받는 인터페이스에 메서드를 정의함으로써 데이터베이스와의 상호작용을 처리할 수 있습니다.
주요 메서드 확인
- save(S entity): 엔티티를 저장하거나 업데이트합니다.
- findById(ID id): ID로 엔티티를 조회합니다.
- findAll(): 모든 엔티티를 조회합니다.
- deleteById(ID id): ID로 엔티티를 삭제합니다.
- count(): 엔티티의 개수를 반환합니다.
- existsById(ID id): 특정 ID의 엔티티 존재 여부를 확인합니다.
커스텀 쿼리란?
JPARepository가 기본적으로 제공하지 않는 특정 요구사항을 만족시키기 위해 작성하는 사용자 정의 쿼리를 의미합니다. 이는 다음과 같은 방법으로 작성할 수 있습니다:
주요 작성 방법
- 메서드 이름 기반 쿼리 메서드(Query Methods)
- @Query 어노테이션을 사용한 JPQL 또는 네이티브 쿼리
- Querydsl을 사용한 동적 쿼리
쿼리 메서드(Query Methods)
// 특정 이메일을 가진 사용자 조회
Optional<User> findByEmail(String email);
// 나이가 특정 값 이상인 사용자 목록 조회
List<User> findByAgeGreaterThan(Integer age);
// 사용자 이름을 기준으로 내림차순 정렬된 사용자 목록 조회
List<User> findAllByOrderByUsernameDesc();
JPQL 사용 예시
@Query("SELECT u FROM User u WHERE u.username LIKE %:keyword%")
List<User> searchUsersByUsername(@Param("keyword") String keyword);
Native Query 사용 예시
@Query(value = "SELECT * FROM user_tb u WHERE u.username LIKE %:keyword%", nativeQuery = true)
List<User> searchUsersByUsernameNative(@Param("keyword") String keyword);
Querydsl 사용 예시
Querydsl은 Java 메서드를 사용하여 엔티티(Entity) 기반으로 타입 안전한 쿼리를 생성하는 프레임워크이다.
// Querydsl을 동적 쿼리
QUser user = QUser.user;
List<User> users = queryFactory.selectFrom(user)
.where(user.username.eq("john").and(user.age.gt(25)))
.fetch();
------------------------------------------------------
// Querydsl을 사용하여 조건에 따라 동적으로 필터링
BooleanBuilder builder = new BooleanBuilder();
if (username != null) {
builder.and(user.username.eq(username));
}
if (age != null) {
builder.and(user.age.gt(age));
}
List<User> users = queryFactory.selectFrom(user)
.where(builder)
.fetch();
커스텀 쿼리의 방법별 특징
- 메서드 이름 기반 쿼리 메서드(Query Methods)
- 자동 생성: 메서드 이름에 따라 자동으로 JPQL 쿼리를 생성합니다.
- 간편성: 간단한 조회 작업에 적합하며, 코드가 간결합니다.
- 한계: 복잡한 조건이나 다중 조인이 필요한 경우에는 한계가 있습니다.
- @Query 어노테이션을 사용한 커스텀 쿼리
- JPQL 쿼리: 엔티티를 대상으로 객체 지향적으로 쿼리를 작성할 수 있습니다.
- 네이티브 쿼리: 실제 SQL을 사용하여 데이터베이스 특정 기능을 활용하거나, 성능을 최적화할 수 있습니다.
- 유연성: 복잡한 쿼리나 특정 요구사항을 충족시킬 수 있습니다.

BoardJPARepository.java
더보기
package com.tenco.blog_v1.board;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.Optional;
// @Repository 생략가능
public interface BoardJPARepository extends JpaRepository<Board, Integer>{
// 커스텀 쿼리 만들어 보기
// Board 와 User 엔티티를 조인하여 특정 Board 엔티티를 조회한다.
@Query("select b from Board b join fetch b.user u where b.id = :id")
Optional<Board> findByIdJoinUser(@Param("id") int id);
}

UserJPARepository.java
더보기
package com.tenco.blog_v1.user;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import java.util.Optional;
public interface UserJPARepository extends JpaRepository<User, Integer> {
// 사용자 이름과 비밀번호를 조회하는 메서드 이름 기반 쿼리를 작성
Optional<User> findByUsernameAndPassword(@Param("username") String username,
@Param("password") String password);
// 사용자 이름
// 메서드 이름 기반
Optional<User> findByUsername(@Param("username") String username);
}
패키지 이름은 user

UserJPARepositoryTest.java

더보기
package com.tenco.blog_v1.user;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import java.util.Optional;
/**
* 패키지명이 동일 해야 한다.
* UserJPARepository 기능을 테스트 하는 클래스 입니다.
*
* DataJpaTest : 어노테이션은 JPA 관련 컴포넌트를 로드하여 테스트 환경을 만들어 준다.
*/
@DataJpaTest
public class UserJPARepositoryTest {
@Autowired
private UserJPARepository userJPARepository;
@Test
@DisplayName("사용자 이름으로 조회하는 테스트")
public void findByUsername_test() {
// given - 테스트에 필요한 초기 조건 설정
String username = "카리나";
// when - 테스트 대상 메서드 실행
Optional<User> userOpt = userJPARepository.findByUsername(username);
// eye ~
System.out.println(username);
System.out.println(userOpt.toString());
// then
}
}

'Spring boot' 카테고리의 다른 글
| 2024.10.16 Blog 프로젝트 만들기(JPA) 댓글 테이블 설계 (엔티티) (1) | 2024.10.16 |
|---|---|
| 2024.10.15 Blog 프로젝트 만들기(JPA) Service 레이어 만들기 (0) | 2024.10.15 |
| 2024.10.14 Blog 프로젝트 만들기(JPA) 리팩토링 (0) | 2024.10.14 |
| 2024.10.11 Blog 프로젝트 만들기(JPA) 인터셉터 만들어 보기 (1) | 2024.10.11 |
| 2024.10.11 Blog 프로젝트 만들기(JPA) 에러 컨트롤러 및 커스텁 익셉션 만들기 (0) | 2024.10.11 |