Home > Spring > πŸƒ[Spring] Spring Data JPAλ₯Ό μ΄μš©ν•΄ λ‹€μ–‘ν•œ 쿼리λ₯Ό μž‘μ„±ν•΄λ³΄μž.

πŸƒ[Spring] Spring Data JPAλ₯Ό μ΄μš©ν•΄ λ‹€μ–‘ν•œ 쿼리λ₯Ό μž‘μ„±ν•΄λ³΄μž.
Spring Framework

πŸƒ[Spring] Spring Data JPAλ₯Ό μ΄μš©ν•΄ λ‹€μ–‘ν•œ 쿼리λ₯Ό μž‘μ„±ν•΄λ³΄μž.

1️⃣ findByName

  • μ‚­μ œ κΈ°λŠ₯을 Spring Data JPA둜 λ§Œλ“€μ–΄ 보기둜 ν–ˆλ‹€!
public class UserService {
    
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // μ‚­μ œ κΈ°λŠ₯.
    public void deleteUser(String name) {
        // SELECT * FROM user WHRER name = ?
        userRepository.findByName(name) // <- 이 μ½”λ“œλŠ” λΉ¨κ°„ κΈ€μ”¨λ‘œ ν‘œμ‹œλ¨.
    }
}
  • findByName()이 λΉ¨κ°„ κΈ€μ”¨λ‘œ ν‘œμ‹œλ˜λŠ” μ΄μœ λŠ” λ©”μ„œλ“œκ°€ μ •μ˜λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.
    • κ·Έλ ‡λ‹€λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒμš”?
      • UserRepository μΈν„°νŽ˜μ΄μŠ€ 내뢀에 β€œν•¨μˆ˜β€λ₯Ό μ •μ˜ν•΄ μ£Όλ©΄ λ©λ‹ˆλ‹€.
public interface UserRepository extends JpaRepository<User, Long> {
    
    User findByName(String name);
}
  • User findByName(String name);
    • findByName ν•¨μˆ˜λŠ” Userλ₯Ό λ°˜ν™˜ν•˜λ©°, name을 parameter(λ§€κ°œλ³€μˆ˜)둜 λ°›μŠ΅λ‹ˆλ‹€.
      • μ΄λ ‡κ²Œ μ •μ˜ν•˜κ³  λ‚˜μ„œ λ‹€μ‹œ UserServiceμ—μ„œ μ‚¬μš©ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€.
public class UserService {
    
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // μ‚­μ œ κΈ°λŠ₯.
    public void deleteUser(String name) {
        // SELECT * FROM user WHRER name = ?
        User user = userRepository.findByName(name);
        if (user == null) {
            throw new IllegalArgumentException();
        }
        
        userRepository.delete(user);
    }
}
  • findByName(String name)은 Userλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    • findByName ν•¨μˆ˜μ—μ„œ Userκ°€ μžˆλ‹€λ©΄ Userλ₯Ό λ°˜ν™˜ν•˜κ³  μ—†λ‹€λ©΄ Null을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • μ›λž˜λΌλ©΄ jdbcRepositoryλ₯Ό μ‚¬μš©ν–ˆλ”λΌλ©΄ DELETE FROM user WHERE name = ?; 이 쿼리λ₯Ό 직접 날렀쀬어야 ν•©λ‹ˆλ‹€.
    • ν•˜μ§€λ§Œ Spring Data JPAμ—μ„œλŠ” 그럴 ν•„μš” 없이 delete()λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

2️⃣ Spring Data JPAμ—μ„œ λ©”μ„œλ“œ 이름을 톡해 쿼리λ₯Ό μžλ™μœΌλ‘œ μƒμ„±ν•˜κΈ°.

  • Spring Data JPAμ—μ„œλŠ” 이름을 톡해 쿼리λ₯Ό μžλ™μœΌλ‘œ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.
    • 이 κΈ°λŠ₯을 ν™œμš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ©”μ„œλ“œ 이름을 νŠΉμ •ν•œ κ·œμΉ™μ— 따라 μž‘μ„±ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    • Spring Data JPAλŠ” λ©”μ„œλ“œ 이름을 νŒŒμ‹±ν•˜μ—¬ 쿼리둜 λ³€ν™˜ν•˜λ―€λ‘œ, μ˜¬λ°”λ₯Έ κ·œμΉ™μ„ λ”°λ₯΄λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.

1️⃣ Spring Data JPAμ—μ„œ λ©”μ„œλ“œ 이름을 μž‘μ„±ν•  λ•Œμ˜ μ£Όμš” κ·œμΉ™.

1️⃣ λ©”μ„œλ“œ μ΄λ¦„μ˜ κΈ°λ³Έ ꡬ쑰.

  • λ©”μ„œλ“œ 이름은 보톡 findBy, readBy, queryBy, countBy λ“±μ˜ μ ‘λ‘μ‚¬λ‘œ μ‹œμž‘ν•©λ‹ˆλ‹€.
    • κ·Έ 뒀에 쑰건으둜 μ‚¬μš©ν•  ν•„λ“œ 이름을 CamelCase λ°©μ‹μœΌλ‘œ μΆ”κ°€ν•©λ‹ˆλ‹€.

πŸ‘‰ κΈ°λ³Έ ꡬ쑰.

[접두사][μ—”ν‹°ν‹°μ˜ ν•„λ“œ 이름][쑰건식]

πŸ‘‰ μ˜ˆμ‹œ.

List<User> findByEmail(String email);
List<User> findByNameAndAge(String name, int age);

2️⃣ 접두사.

  • λ©”μ„œλ“œ 이름은 보톡 λ‹€μŒκ³Ό 같은 μ ‘λ‘μ‚¬λ‘œ μ‹œμž‘ν•©λ‹ˆλ‹€.
    • findBy : νŠΉμ • 쑰건에 λ§žλŠ” μ—”ν‹°ν‹°λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
    • readBy : findBy와 λΉ„μŠ·ν•œ μ—­ν• λ‘œ 데이터λ₯Ό μ‘°νšŒν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
    • queryBy : 데이터 쑰회 μ‹œ μ‚¬μš©.
    • countBy : νŠΉμ • 쑰건에 λ§žλŠ” μ—”ν‹°ν‹° 개수λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
    • existsBy : νŠΉμ • 쑰건에 λ§žλŠ” μ—”ν‹°ν‹°κ°€ μ‘΄μž¬ν•˜λŠ”μ§€ μ—¬λΆ€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.
    • deleteBy : νŠΉμ • 쑰건에 λ§žλŠ” μ—”ν‹°ν‹°λ₯Ό μ‚­μ œν•©λ‹ˆλ‹€.

3️⃣ 쑰건 μ—°κ²° ν‚€μ›Œλ“œ.

  • μ—¬λŸ¬ ν•„λ“œλ₯Ό 쑰건으둜 μ‚¬μš©ν•  λ•ŒλŠ” λ‹€μŒκ³Ό 같은 ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 쑰건을 μ—°κ²°ν•©λ‹ˆλ‹€.
    • And : 두 쑰건을 λͺ¨λ‘ λ§Œμ‘±ν•˜λŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
    • Or : 두 쑰건 쀑 ν•˜λ‚˜λΌλ„ λ§Œμ‘±ν•˜λŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.

πŸ‘‰ μ˜ˆμ‹œ

List<User> findByNameAndAge(String name, int age);
List<User> findByNameOrEmail(String name, String email);

4️⃣ μ—°μ‚°μž ν‚€μ›Œλ“œ.

  • Spring Data JPAλŠ” λ‹€μ–‘ν•œ μ—°μ‚°μ§€ ν‚€μ›Œλ“œλ₯Ό μ§€μ›ν•˜μ—¬ ν•„λ“œ 값에 쑰건을 λΆ€μ—¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • Comparison(비ꡐ)
      • IsNull, IsNotNull : 값이 null인지 μ•„λ‹Œμ§€λ₯Ό μ²΄ν¬ν•©λ‹ˆλ‹€.
      • IsTrue, IsFalse : Boolean 값이 true λ˜λŠ” false인지 μ²΄ν¬ν•©λ‹ˆλ‹€.
      • LessThan, LessThanEqual : 값이 μ§€μ •λœ 값보닀 μž‘κ±°λ‚˜, μž‘κ±°λ‚˜ 같은 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
      • GreaterThan, GreaterThanEqual : 값이 μ§€μ •λœ 값보닀 ν¬κ±°λ‚˜, ν¬κ±°λ‚˜ 같은 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
      • Between : 두 κ°’ 사이에 μžˆλŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
    • String Operations(λ¬Έμžμ—΄ μ—°μ‚°)
      • Like : SQL의 LIKE와 같이 νŠΉμ • λ¬Έμžμ—΄ νŒ¨ν„΄μ΄ ν¬ν•¨λœ 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
      • StartingWith : νŠΉμ • λ¬Έμžμ—΄λ‘œ μ‹œμž‘ν•˜λŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
      • EndingWith : νŠΉμ • λ¬Έμžμ—΄λ‘œ λλ‚˜λŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
      • Containing : νŠΉμ • λ¬Έμžμ—΄μ„ ν¬ν•¨ν•˜λŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
    • Collection Operations(μ»¬λ ‰μ…˜ μ—°μ‚°)
      • In : μ£Όμ–΄μ§„ μ»¬λ ‰μ…˜μ— 값이 ν¬ν•¨λ˜λŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
      • NotIn : μ£Όμ–΄μ§„ μ»¬λ ‰μ…˜μ— 값이 ν¬ν•¨λ˜μ§€ μ•ŠλŠ” 경우λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.

πŸ‘‰ μ˜ˆμ‹œ

List<User> findByAgeGreaterThan(int age);
List<User> findByNameStartingWith(String prefix);
List<User> findByEmailContaining(String keyword);
List<User> findByIdIn(List<Long> ids);

5️⃣ μ •λ ¬ν•˜κΈ°

  • 정렬이 ν•„μš”ν•œ 경우 OrderBy ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•„λ“œ 이름과 λ°©ν–₯(Asc λ˜λŠ” Desc)을 μ§€μ •ν•©λ‹ˆλ‹€.

πŸ‘‰ μ˜ˆμ‹œ

List<User> findByNameOrderByAgeAsc(String name);
List<User> findByNameOrderByAgeDesc(String name);

6️⃣ νŽ˜μ΄μ§• 및 μ •λ ¬ νŒŒλΌλ―Έν„°

  • Spring Data JPAλŠ” Pageable 및 Sort νŒŒλΌλ―Έν„°λ₯Ό μ§€μ›ν•˜μ—¬, λ©”μ„œλ“œ 이름에 OrderByλ₯Ό μΆ”κ°€ν•˜μ§€ μ•Šκ³ λ„ μ •λ ¬κ³Ό νŽ˜μ΄μ§•μ„ μ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ‘‰ μ˜ˆμ‹œ

Page<User> findByAgeGreaterThan(int age, Pageable pageable);
List<User> findByName(String name, Sort sort);

7️⃣ λ³΅μž‘ν•œ 쿼리 μž‘μ„± μ˜ˆμ‹œ

  • κ·œμΉ™μ„ μ μš©ν•˜μ—¬ λ‹€μ–‘ν•œ 쑰건을 ν¬ν•¨ν•œ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    List<User> findByNameAndAgeGreaterThan(String name, int age);
    List<User> findByEmailContainingAndIsActiveTrue(String keyword);
    List<User> findByCreatedAtBetween(Date startDate, Date endDate);
    List<User> findByLastNamesStartingWithAndAgeLessThanOrderByAgeDesc(String prefix, int age);
    

3️⃣ μš”μ•½.

    1. 접두사 : findBy, countBy, existsBy, deleteBy 등을 μ‚¬μš©.
    1. 쑰건 μ—°κ²° : And, Or을 μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ 쑰건을 μ—°κ²°.
    1. μ—°μ‚°μž : IsNull, IsTrue, LessThan, GreaterThan, Containing, Like, Between 등을 μ‚¬μš©ν•˜μ—¬ ν•„λ“œμ— λ‹€μ–‘ν•œ 쑰건 적용.
    1. μ •λ ¬ : OrderBy와 Asc λ˜λŠ” Descλ₯Ό μ‚¬μš©ν•˜μ—¬ μ •λ ¬ 쑰건을 μΆ”κ°€.
    1. νŽ˜μ΄μ§•κ³Ό μ •λ ¬ νŒŒλΌλ―Έν„° : Pageableκ³Ό Sort νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ νŽ˜μ΄μ§• 및 μ •λ ¬ κ°€λŠ₯.