프로그래밍/스프링

[스프링] 9. 쿼리메소드

riroan 2022. 8. 10. 06:09

지난 시간에 JPA를 이용하여 findById, findAll등의 메소드를 사용하여 데이터베이스에 접근할 수 있다는 것을 알았다.

그때는 간단하게만 살펴보았는데 복잡한 SQL문을 처리하고 싶을 수 있다.

SQL문의 꽃이라고 볼 수 있는 select, from, where등을 사용할 수 있도록 하는 메소드가 쿼리메소드이다.

 

// repository/UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByName(String name);
}

위 메소드를 정의하고 테스트해보자.

 

// test/repository/UserRepositoryTest.java

@SpringBootTest
class UserRepositoryTest {
    @Autowired
    private UserRepository userRepository;


    @BeforeEach
    void before() {
        User user1 = new User("Alice", "alice@naver.com");
        User user2 = new User("Bob", "bob@naver.com");
        User user3 = new User("Charlie", "charlie@gmail.com");
        User user4 = new User("David", "david@gmail.com");
        User user5 = new User("Alice", "alice@gmail.com"); // 1과 같은 이름 다른 이메일!!
        userRepository.saveAll(Lists.newArrayList(user1, user2, user3, user4, user5));
    }

    @Test
    void test(){
        List<User> users = userRepository.findByName("Alice");
        for(User user : users)
            System.out.println(user);
    }
}

@BeforeEach 어노테이션을 사용하여 각 테스트가 시작하기 전 호출할 코드를 작성했다.

테스트가 시작하기 전 5명의 유저를 repository에 추가했다.

 

그리고 Alice라는 유저의 이름을 모두 찾도록 코드를 작성했다.

쿼리문이 출력되었고 user0_.name=? 라는 부분이 보인다. (쿼리문은 지난시간 application.yml를 설정해서 나온 것이다.)

?는 쿼리메소드를 사용할 때 들어간 인자이다.

 

이렇게 인터페이스에 메소드를 정의만 해도 사용할 수 있다!

 

쿼리메소드의 여러가지 예시를 알아보자.

 

- 필드가 존재한다면 원하는 필드를 찾는 용도로 사용할 수 있다.

// repository/UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findById(Long id);
    
    List<User> findByName(String name);
    
    User findByEmail(String email); // 하나만 받을 수 있다!!
}

 

- 여러개의 조건을 걸 수도 있다.

// repository/UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByIdAndByName(Long id, String name);
    
    User findByNameAndByEmail(String name, String email);
}

 

- 날짜같은 경우는 ~~이후, ~~이전 같은 형식을 자주 사용한다.

// repository/UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByCreatedAtGreaterThan(LocalDateTime startTime);

    List<User> findByCreatedAtLessThanEqual(LocalDateTime endTime);

    List<User> findByCreatedAtBetween(LocalDateTime startTime, LocalDateTime endTime);
}

 

- 문자열에서 포함여부를 판단할 수 있다.

// repository/UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByNameStartingWith(String prefix); //prefix로 시작

    List<User> findByNameEndingWith(String postfix); //postfix로 끝남

    List<User> findByNameContains(String pattern); //pattern이 포함됨
}

 

- 정렬도 수행할 수 있다.

// repository/UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findTop5ByNameOrderByIdAsc(String name); // Id로 오름차순 정렬, Top 5개 반환
}

 

더 많은 정보는 아래 링크를 참고하자

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

'프로그래밍 > 스프링' 카테고리의 다른 글

[스프링] 8. JPA  (0) 2022.08.04
[스프링] 7. Object Relational Mapping  (0) 2022.08.02
[스프링] 6. 테스트코드 작성  (0) 2022.08.02
[스프링] 5. Lombok  (0) 2022.07.22
[스프링] 4. Object Mapper  (0) 2022.07.18