패스트 캠퍼스의 강의 [한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지]를 보고 정리한 글입니다.
@Query란?
Query Method 의 커스텀 버전!
- 일반적으로 @Query까지는 필요가 없으나 2가지의 경우 @Query를 쓰는 게 더 낫다
- 긴 쿼리메소드의 이름을 가독성이 좋게 수정이 필요한 경우
- 엔티티 전체가 아닌 필요한 컬럼만 부분적으로 조회가 필요한경우
1. Query Method의 가독성 문제
= Query Method의 이름의 길이가 길 경우
- 여러가지 조건이 있는 경우 메소드명이 길어질 수 밖에 없음.
- ex)findByCatrgoryIsNullAndName....
더보기
Test 해보는 경우 ->쿼리가 잘 생성되었지만 값이 안나올 수 있음 -> 디버깅 -> 조건이 null 값이 들어가있음..
- 코드 상 수정 가능 ...
=> 테스트에서 사전에 문제가 있음을 확인할 수 있도록 코딩하는 것이 중요- 수정방법 (조건을 추가해줌)
- data.sql을 고침
- 그러면 계속 data를 넣어줄때마다 계속 조건부분을 넣어줘야함.. (null이 생길수 있음)
- entity에 추가해주기
- @Column(columnDefinition="디폴트 값을 지정") /
- =>Auto DDL의 속성
- => sql type을 치환하는 것 / 각각의 속성이 이어 붙음 (유효성 확인 안함)
- =>comment: 로 주석 처리도 가능
- data.sql을 고침
- 수정방법 (조건을 추가해줌)
- 이렇게 쿼리메소드명이 긴 경우 where 절이 어떻게 작용하는지 알기 어려움.
- @Query를 사용하면 된다!
@Query(value = "select b from Book b where name = ?1 and createdAt >= ?2 and updateAt >= ?3 and category is null")
List<book> findByRecently (String name, LocalDateTime createdAt, LocalDateTime updateAt);
- 쿼리를 만들때 매개변수를 넣어주는 방법
- ?1 , ?2 ,?3 이라는 ?숫자를 사용 해당 메소드에서 몇번째에 있는 파라미터값인지를 치환함 (1base index 이므로 1부터 시작함)
- (value = "select b from Book b where name = ?1 and createdAt >= ?2 and updateAt >= ?3 and category is null")
- 꼭 파라미터 순서가 순차적일 필요는 없음. 숫자로 매핑해주는 방식임.(그러나 되도록 순차적으로)
- 자바에서는 순서에 의존성을 가지는 파라미터 매핑 방식은 지양함
- 언제든 파라미터가 추가되거나 하면서 사이드 이펙트의 확률이 높아짐.
- (조금더 권장하는 방식) name 기반의 파라미터 매핑
- ?1 , ?2 ,?3 이라는 ?숫자를 사용 해당 메소드에서 몇번째에 있는 파라미터값인지를 치환함 (1base index 이므로 1부터 시작함)
@Query(value = "select b from Book b where name = :name and createdAt >= :createdAt and updateAt >= :updateAt and category is null")
List<book> findByRecently (@Param("name") String name, @Param("createdAt") LocalDateTime createdAt, @Param("updateAt") LocalDateTime updateAt);
- @Param("name") String name. ... 이런식
- 매개변수의 순서에 영향을 받지 않기 때문에 추가가되거나 사이드이펙트에서 좀 더 자유로움
🚨중요한 점 : JPQL !🚨
- JPA entity를 기반으로 하는 쿼리를 생성
- java 객체를 활용할수 있는 sql 구문!
- Table 이름이 아닌 Entity로
- Entity내에 존재하는 field이름
- JPQL의 장점
- 방언 dialect : 방언을 통해서 DB의 종류에 따라 서로다른 쿼리를 자동으로 생성해줌
- native 쿼리와 차이가 있음
- 실제로는 쿼리메소드로 만드는 것과 비슷한 과정으로 생성
2. 엔티티에 연결되지 않은 쿼리가 가능함.
=> 필요한 컬럼들만 추려서 조회가 가능함.
@Query(value = "select b.name as name, b.category as category from Book b")
List<BookNameAndCategory> findBookNameAndCategory();
- 이런 식으로 필요한 컬럼만 추려서 조회 가능함.
👀 java 객체를 활용할 수 있는 sql 구문도 있음!
@Query(value = "select new com....(풀네임 적기)BookNameAndCategory(b.name, b.category) from Book b") => 가능함!
List<BookNameAndCategory> findBookNameAndCategory();
- 객체생성해서도 가능하지만 com.xxxx.xxxx...entity 이런식으로 풀네임을 적어줘야함.
추가적으로 @Query를 좀더 잘 활용할 수 있는 방법!
: Pagable : 자동적으로 페이징하는 것
@Query(value = "select b.name as name, b.category as category from Book b")
Page<BookNameAndCategory> findBookNameAndCategory(Pagable pagable);
☝메세지 오버로딩 : 메소드명은 같지만 파라미터가 다르면 둘다 선언 가능함. 이를 메세지 오버로딩이라고 함.
🚩@Query를 사용함으로써
- 긴 쿼리메소드의 이름을 가독성이 좋게 수정 가능
- 엔티티 전체가 아닌 필요한 컬럼만 부분적으로 추출하여 조회 가능
- 추출할때는 인터페이스형식 / DTO 형식으로 클래스를 선언하여서 추출 가능
- 페이징 기능도 아주 쉽게 추가할수 있도록 지원
🧨다만 JPA 이 문법이 어려워서 JPQL을 사용하는 것 보다는 각각의 용도에 맞는 쓰임새가 있으므로 각각의 방법을 숙지하고 적절한 때에 사용하기!
'🌿SPRING > 🍀공부 [SPRING]' 카테고리의 다른 글
[SPRING][JPA] native query 활용하기 (0) | 2022.09.29 |
---|---|
[SPRING][JPA] 다대다 매핑 N:M (0) | 2022.09.26 |
[SPRING] Service 와 ServiceImpl (0) | 2022.09.14 |
[SPIRING] [MVC] @EnableWebMvc 어노테이션 (0) | 2022.09.07 |
[SPRING] Frontend와 협업 ! - CORS 원리 / 설정 (22.10.22 수정) (0) | 2022.09.07 |