Spring Data JPA 메서드 이름 기반 쿼리 생성의 규칙

Seong Hyeon Kim·2024년 7월 18일
0

스프링

목록 보기
2/9

User 엔티티와 Profile 엔티티를 사용하여 Spring Data JPA에서 메서드 이름을 기반으로 한 쿼리 생성에 대해 다시 한 번 정리하겠습니다.

Spring Data JPA에서 메서드 이름 기반 쿼리 생성

Spring Data JPA는 메서드 이름을 기반으로 쿼리를 자동으로 생성합니다. 이를 통해 복잡한 SQL 쿼리를 작성하지 않고도 다양한 조건으로 데이터를 조회할 수 있습니다. 메서드 이름을 통해 쿼리를 생성하는 규칙과 그 사용법을 설명하겠습니다.

1. 메서드 쿼리 정의 규칙

1. 메서드 이름의 기본 구조

메서드 이름은 다음과 같은 기본 구조를 따릅니다:

  • 접두사: findBy, readBy, getBy, queryBy, countBy, existsBy 등.
  • 엔티티 속성: 조회 조건에 사용할 엔티티의 속성 이름.
  • 연산자: And, Or, LessThan, GreaterThan, Between, Like, In 등.

2.주요 접두사

  • findBy: 엔티티를 조회합니다.
  • readBy: 데이터를 읽습니다.
  • getBy: 데이터를 가져옵니다.
  • queryBy: 데이터를 쿼리합니다.
  • countBy: 조건에 맞는 엔티티의 개수를 셉니다.
  • existsBy: 조건에 맞는 엔티티가 존재하는지 확인합니다.

3. 예시: UserProfile 엔티티

User 엔티티
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Column;

@Entity
public class User {

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

    @Column(name = "username", nullable = false, unique = true)
    private String username;

    // 기타 필드 및 게터와 세터

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}
Profile 엔티티
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;

@Entity
public class Profile {

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

    @ManyToOne
    @JoinColumn(name = "user_id", referencedColumnName = "username", nullable = false)
    private User user;

    private String profileName;

    // 기타 필드 및 게터와 세터

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getProfileName() {
        return profileName;
    }

    public void setProfileName(String profileName) {
        this.profileName = profileName;
    }
}



메서드 쿼리 생성 예시

1. ProfileRepository 정의

Profile 엔티티를 username을 기준으로 조회하는 메서드를 정의합니다.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface ProfileRepository extends JpaRepository<Profile, Long> {
    List<Profile> findByUserUsername(String username);
}

2. 서비스 클래스

서비스 클래스에서 정의한 리포지토리 메서드를 사용합니다.

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 ProfileService {

    @Autowired
    private ProfileRepository profileRepository;

    @Transactional(readOnly = true)
    public List<Profile> findProfilesByUsername(String username) {
        return profileRepository.findByUserUsername(username);
    }
}

3. 컨트롤러

컨트롤러에서 서비스 메서드를 호출하여 결과를 반환합니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/profiles")
public class ProfileController {

    @Autowired
    private ProfileService profileService;

    @GetMapping("/find-by-username")
    public ResponseEntity<?> findByUsername(@RequestParam String username) {
        List<Profile> profiles = profileService.findProfilesByUsername(username);
        if (!profiles.isEmpty()) {
            return ResponseEntity.ok(profiles);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}



메서드 이름의 의미

@Repository
public interface ProfileRepository extends JpaRepository<Profile, Long> {
    List<Profile> findByUserUsername(String username);
}
  1. findBy: 데이터베이스에서 데이터를 검색한다는 의미입니다.
  2. UserUsername: Profile 엔티티에서 User 엔티티와 연관된 속성인 username을 기준으로 검색한다는 의미입니다.
  3. (String username): 메서드가 username이라는 문자열 파라미터를 받아 검색 조건으로 사용한다는 의미입니다.



결과 쿼리 생성

Spring Data JPA는 findByUserUsername 메서드 이름을 해석하여 다음과 같은 JPQL 쿼리를 자동으로 생성합니다:

SELECT p FROM Profile p WHERE p.user.username = ?1

위 쿼리에서 pProfile 엔티티의 별칭이고, p.user.usernameProfile 엔티티에 연관된 User 엔티티의 username 속성을 의미합니다. ?1은 메서드의 첫 번째 파라미터(username)를 의미합니다.

정리

  • 메서드 이름 규칙: Spring Data JPA는 메서드 이름을 기반으로 쿼리를 자동 생성합니다. findBy, readBy, getBy 등 접두사와 엔티티의 속성 이름을 조합하여 쿼리를 정의합니다.

  • 조건 기반 쿼리: 메서드 이름에 조건을 포함시켜 다양한 쿼리를 생성할 수 있습니다. 예를 들어 findByUserUsernameProfile 엔티티에서 User 엔티티의 username을 기준으로 검색합니다.

  • 파라미터: 메서드 파라미터는 쿼리 조건으로 사용됩니다. 메서드 이름과 일치하는 엔티티의 속성 타입을 사용합니다.

  • 결과 쿼리 생성: Spring Data JPA는 메서드 이름을 해석하여 적절한 JPQL 쿼리를 자동으로 생성합니다.
    예를 들어, findByUserUsername 메서드는
    SELECT p FROM Profile p WHERE p.user.username = ?1
    쿼리를 생성합니다.

이를 통해 Spring Data JPA에서 메서드 이름을 기반으로 한 쿼리 생성을 이해하고, 필요한 쿼리를 쉽게 정의하고 사용할 수 있습니다.

profile
삽질도 100번 하면 요령이 생긴다. 부족한 건 경험으로 채우는 개발자

0개의 댓글