[Spring] Spring Data JPA에서 첫 번째 엔티티 조회 방법


환경

  • Java


방법

여러가지 방법이 있는데 아래에서는 2가지 방법을 소개한다. 예시와 함께 사용 방법을 테스트를 통해 정리했다. JPQL에서 LIMIT 1을 사용할 수 없어서 조사하다가 찾은 내용을 정리한다.

  1. JPA Query Methods를 이용한 방법
  2. Pageable을 이용한 방법


사용법과 예시

build.gradle

  • 아래 build.gradle은 개인 프로젝트 환경마다 다를 수 있다.
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.1.5'
	id 'io.spring.dependency-management' version '1.1.3'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '21'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	compileOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
	testImplementation 'org.junit.jupiter:junit-jupiter'
	testImplementation 'org.junit.jupiter:junit-jupiter-api'
	testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

tasks.named('bootBuildImage') {
	builder = 'paketobuildpacks/builder-jammy-base:latest'
}

tasks.named('test') {
	useJUnitPlatform()
}

UserEntity

  • 예시로 사용할 Entity
package com.example.practice.entity;

import jakarta.persistence.*;
import lombok.*;


@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "email")})
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String gender;

    @Column(nullable = false)
    private String type;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;
}

UserRepository

  1. JPA Query Methods를 이용한 방법
    • 정해진 메소드 이름 규칙에 따라서만 만들면 된다.
    • 해당 방법의 경우 아래 예제를 보거나 공식 문서를 보면 쉽게 찾을 수 있다.
  2. Pageable을 이용한 방법
    • 예제에서는 @Query를 사용했으며 List로 반환하고 Pageable을 끝에 넘겨주면 된다.
    • 사용 방법은 아래 테스트에서 볼 수 있다.
package com.example.practice.repository;

import com.example.practice.entity.UserEntity;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {
    // 1. JPA Query Methods를 이용한 방법
    UserEntity findFirstByGenderAndTypeOrderByIdDesc(String gender, String type);

    // 2. Pageable을 이용한 방법
    @Query("SELECT u FROM UserEntity u WHERE u.gender = :gender AND u.type = :type ORDER BY u.id DESC")
    List<UserEntity> findFirstByGenderAndTypeOrderByIdDescUsingPageable(@Param("gender") String gender, @Param("type") String type, Pageable pageable);
}

UserRepositoryTest

  1. JPA Query Methods를 이용한 방법
    • 하단의 예시처럼 메소드를 호출하면 된다.
  2. Pageable을 이용한 방법
    • PageRequest.of(0, 1)를 넘겨준다.
    • PageRequest.of(0, 1): 첫 번째 페이지에서 한 개의 결과를 가져오도록 하는 설정
package com.example.practice.repository;

import com.example.practice.entity.UserEntity;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.List;

@ExtendWith(SpringExtension.class)
@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void findFirstByGenderAndTypeOrderByNameDescTest() {

        List<UserEntity> userEntities = Arrays.asList(
                UserEntity.builder().
                        email("test1@test.com")
                        .username("testUsername1")
                        .password("testPassword1")
                        .gender("male")
                        .type("A")
                        .build(),
                UserEntity.builder()
                        .email("test2@test.com")
                        .username("testUsername2")
                        .password("testPassword2")
                        .gender("female")
                        .type("A")
                        .build(),
                UserEntity.builder()
                        .email("test3@test.com")
                        .username("testUsername3")
                        .password("testPassword3")
                        .gender("male")
                        .type("A")
                        .build(),
                UserEntity.builder()
                        .email("test4@test.com")
                        .username("testUsername4")
                        .password("testPassword4")
                        .gender("male")
                        .type("B")
                        .build(),
                UserEntity.builder()
                        .email("test5@test.com")
                        .username("testUsername5")
                        .password("testPassword5")
                        .gender("female")
                        .type("A")
                        .build()
        );
        userRepository.saveAll(userEntities);

        // 1. JPA Query Methods를 이용한 방법
        UserEntity resultUser = userRepository.findFirstByGenderAndTypeOrderByIdDesc("male", "A");
        Assertions.assertEquals("test3@test.com", resultUser.getEmail());

        // 2. Pageable을 이용한 방법
        List<UserEntity> resultUsers = userRepository.findFirstByGenderAndTypeOrderByIdDescUsingPageable("male", "A", PageRequest.of(0, 1));
        Assertions.assertEquals("test3@test.com", resultUsers.getFirst().getEmail());
    }
}


참고자료