본문 바로가기

FastCampus - 한번에 끝내는 Java|Spring 웹 개발/04 JPA

JPA Ch 3 Query Method (2~3) - 패스트캠퍼스 챌린지 21일차

어제에 이어서 기본실습 2 (1, 2) 입니다. 추가적으로 메소드를 뭘 더 만들수 있는지 보는 것 외에는 따로 유의미한 걸 진행하지는 않았습니다. 쿼리 메소드라는게 뭘 쓸 수 있을지 알아야지 쓸 수 있는거니까 그게 중요하긴 하겠죠???

And / Or

List<User> findByEmailAndName(String email, String name)

직관적입니다. And 와 Or 로 데이터의 여러 필드를 조건으로 걸어서 검색할 수 있습니다. 쿼리의 where 절에 해당 조건이 들어갑니다.

딱 하나 궁금했던 부분은 And와 Or 을 여러번 쓰면 어떻게 되나였는데, 쿼리에 그대로 나오더군요...

fun findByNameAndIdOrEmail(name: String, id: Long, email: String): User?
    where
        user0_.name=? 
        and user0_.id=? 
        or user0_.email=?

After / Before / GreaterThan[Equal] / LessThan[Equal]

After, Before 와 GreaterThan, LessThan 의 의미는 같지만, 가독성을 위해 두 개를 구분해서 사용합니다.

  • After, Before: 시간에 조건을 걸 때 자연스럽습니다.
    List<User> findByCreatedAtAfter(LocalDateTime from)
    • 등호는 포함하지 않는다는 점에 유의
    • userRepo.findByCreatedAtAfter(LocalDateTime.now().minusDays(1))
  • GreaterThan / LessThan: 숫자일 때 쓰는게 자연스럽습니다.
    뒤에 Equal 을 붙여서 포함 비교(<= 등)도 가능합니다.
    List<User> findByIdGreaterThanEqual(Long id)

쿼리에는 where 절에 부등호가 붙습니다.

    where
        user0_.created_at>?

Between

쿼리의 where 절에 between 이 나옵니다. 범위니까 양방향 다 해당 지점을 포함합니다.

List<User> findByIdBetween(Long id1, Long id2)

사용 방법만 아는 것보다는 실제로 어떤 쿼리가 실행되는지 아는 게 중요하다고 하시네요.

중요한 건 여러번 강조해도 지나치지 않겠죠?


빈 값 찾기: IS_NULL / IS_EMPTY 혹은 사이에 NOT

(IS_(NOT_)?(NULL|EMPTY))

두 개가 동작이 좀 다릅니다. null 은 진짜 DB 상에서 null 인지 확인하고 empty 는 컬렉션에 대해 동작합니다.

  • IS_NULL / IS_NOT_NULL: 해당 필드가 (DB에서) null 인지 확인합니다.
    쿼리는 where 절에 is null 이 나온다네요.
    • fun findByIdIsNotNull(): List<User> 은 ID가 null 이 아닌 거고, ID는 p.key 니까 전체가 나오겠죠.
  • IS_EMPTY / IS_NOT_EMPTY 는 필드가 컬렉션 타입일 때 사용합니다.
    "문자열이 비었는지 확인하는 게 아니다" 를 강조하기 위해서 넣으셨다네요.
    쿼리는 where exists ( 이너 쿼리 ) 형태로 동작합니다.
    • Spring 문서에서 찾기가 어렵습니다.
      있긴 있는데 Query Creation 섹션이 아닌 부록에 있으며, IntelliJ 도 오류라고 생각합니다. 동작은 잘 되네요.
      문서에서는 특정 저장소의 문서를 확인해보라고 되어있습니다.
    • 실습을 위해 컬렉션 필드가 릴레이션으로 추가되었는데, 이건 나중에 배우게 될 거라 지금은 중요하지 않아보이네요. 쿼리문에 Address 를 조회하는 내용도 생기므로 보는 데 방해가 되어 다시 주석처리하고 진행하셨습니다.
          @OneToMany(fetch = FetchType.EAGER)
          private List<Address> addresses;​

      @Data
      @Entity
      public class Address {
          @Id
          private Long id;
      }

True, False

뻔하다고 스킵, 문서에 따르면 where x.active = true 같은 형태랍니다. 진짜로 뻔하네요.

In / NotIn

찾으려는 대상이 리스트인 경우 사용합니다.
findByNameIn(List<String> names)
(* where user.name in (?, ?) ) -> 강의에서 나온 쿼리인데, 거기서는 ID 목록을 배열로 만들어서 이럴겁니다.

자주 쓴다는데, 이 함수를 바로 호출하는 경우보다는 다른 쿼리의 결과를 이게 있는 쿼리 메소드에 넣는 일이 많답니다. (예를 들자면 ID 리스트라던가)

주의할 점은 퍼포먼스로, In 으로 들어가는 패러미터의 개수가 많아진다면...

like 의 래핑: endingWith / startingWIth / contains

문자열 비교.
findByNameLike( "%tintin%" )

like 쿼리를 때리는데, SQL에서 검색하려면 플레이스홀더로 % 를 넣어야 하므로 그게 래핑되어있는 쿼리메서드라고 합니다.

  • like: 검색 문자열을 직접 입력
    findByNameLike( "%tintin%" )
    (where name like ? escape ?)
  • 나머지는 뻔하죠? 적당히 %가 들어갈게 분명합니다.

Is / Equals / 혹은 기재하지 않기

제일 처음에 실습했던 findByName 이 이 케이스입니다. 다음 세 가지는 동일합니다.

  • findByName(String name)
  • findByNameIs(String name)
  • findByNameEquals(String name)
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스: https://bit.ly/37BpXiC

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #한번에끝내는JavaSpring웹개발마스터초격차패키지Online

오늘은 이상하게 졸려