[그린컴퓨터] Server/Spring

쿼리메서드 { JpaRepository 아쉬운점, 개요, 쿼리메서드 이름생성 규칙, @Transactional, 예제 }

Ben의 프로그램 2023. 7. 11. 13:49
728x90
JpaRepository 의 아쉬운 점?
이전 Memo 예제에서 JpaRepository 인터페이스를 상속받은 MemoRepository 인터페이스는 JpaRepository 에서 제공하는 기본적인 CRUD 메서드를 사용할 수 있었는데요. 필요에 따른 조건 검색과 같이 좀 더 까다로운 작업을 수행해야 할 때는 JpaRepository 에서 제공하는 기본 메서드만으로는 한계가 있습니다. JPA는 조건검색을 처리 하기 위해 쿼리메서드, @Query, Querydsl 을 제공합니다. 

 

쿼리메서드 간단하게 살펴보기
-) 쿼리메서드
: 쿼리메서드는 말 그대로 메서드 이름 자체가 쿼리문이 됩니다. 예를 들어보겠습니다. 우선 쿼리메서드와 같은 것들은 JPA 가 기본으로 제공하는 것이 아니기 때문에 JPA가 트랜잭션 처리를 자동으로 해주지 못합니다.

따라서 트랜잭션 처리를 할 수 있도록 MemoRepository 에 @Transactional 어노테이션을 추가해주어야 합니다.

그 다음 MemoRepository 에 List<Memo> findByNoLessThan(int mno); 이런 코드를 추가해주면 테스트 파일에서 해당 메서드를 사용할 수 있습니다. 

위와 같이 MemoRepository 에서 정의한 쿼리메서드를 사용할 수 있습니다. 

 

쿼리 메서드 공식 문서
다음  URL 에 들어가면 Spring 공식문서에서 쿼리 메서드 부분을 볼 수 있다. 
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation


SQL 에서 사용자 하는 구문을 Keyword 에서 찾아서 Sample 을 참고하여 쿼리메서드를 작성할 수 있습니다. 

 

쿼리 메서드 이름 생성 규칙
쿼리 메서드 이름을 만드는 규칙은 다음과 같습니다. 

1. 메서드 이름은 findBy 또는 getBy 로 시작한다.

2. 특정 컬럼만 검색하고 싶다면 findBy 에서 findnoBy 처럼 컬럼을 적어준다

3. 검색하려는 엔티티(테이블) 이름이 findBymemo 처럼 뒤에 이어진다.

4. 조건식을 만드는 키워드인 And, Or, Between, Like, Orderby 들은 마지막에 추가합니다. (사용법은 Spring 공식문서 참고)

 

쿼리 메서드 이름 예시 1
예시를 한번 살펴보겠습니다. 

우선 Repository 먼저 살펴보겠습니다. 위에서 한번 말했다 싶이 Repository 에서 쿼리메서드를 추가하면 JPA가 기본으로 제공하는 메서드가 아니기 때문에 트랜잭션을 개발자가 처리해주어야 하는데, @Transactional 애노테이션을 Repository 에 추가해주면 됩니다. 그 다음 쿼리메서드를 보면 List< > 로 리스트 자료구조 반환 값이 있는 것을 볼 수 있는데, 조건 검색의 결과로 나오는 값을 List에 담아서 반환하게 됩니다. 반환 값으로 List<Memo> 를 사용하였고 findBy 로 작성하여서 Memo 테이블에 있는 모든 컬럼을 조회합니다. No 가 조건 검색의 기준 컬럼임을 확인할 수  있고 LessThan 키워드로 int mno 매개변수 보다 값이 작은 No 에 해당하는 Memo 를 검색하여 출력하게 됩니다. 키워드에 따른 매개변수 사용은 위에서 언급한 Spring 공식 문서를 확인하는 것이 가장 편하고 정확합니다. 

실제로 쿼리 메서드를 사용한 것을 보면 반환 값으로 List 를 받아서 검색된 값을 하나씩 꺼내서 확인하는 것을 볼 수 있습니다. 

 

쿼리 메서드 이름 예시들 (@Transactional)
이번에는 쿼리 메서드 이름들을 예시만 들어보겠습니다. 위에 설명을 다 이해하였다면 다음 쿼리메서드들을 이해하기는 어렵지 않을 겁니다. 

살펴볼 점이라면 @Transaction 을 사용해야한다는 점, 조건 검색 말고 Delete 역할을 수행하는 쿼리 메서드도 있다는 것을 확인할 수 있습니다. 

@Transactional 을 사용해야 하는 이유는 아래 그림과 같습니다.