본문 바로가기

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

JPA Ch 3 Query Method (1) - 패스트캠퍼스 챌린지 20일차

너X킹-chan 이랑 인사하세요!
이미지에 없는 아래쪽에 챕터 3의 강의가 더 있음

오늘은 의욕이 별로 안 나는 날이라 강의는 하나만 나가기로 했습니다. 그런데 웬걸 결국 더 찾아보게 되던... 다만 더 찾아본 거에 비하면 큰 소득은 없었습니다.

Query Method

interface 로 정의했던 MyRepository 에 신기하게도 특정 규칙에 맞춰서 메소드를 정의하기만 하면, 신기하게도 (짜잔!) 함수 본문이 없는데도 메소드의 이름 대로 동작합니다. 이게 Query Method 입니다. 강사님 말씀하시길, 적은 노력으로도 손쉽게 짤 수 있다고 (가성비가 좋다는 얘기죠).

규칙은 레퍼런스 문서를 참조하시면 되구요. 여기에서 사용 가능한 패턴이나 반환형 등을 살펴보실 수 있습니다.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

무려 IDE가 자동완성을 지원해주기까지 합니다. 이건 언어적인 부분이 아니니까 스프링을 겨냥해서 만들어진 기능이겠죠.

메소드 정의 및 실습 1강에서는 findBy[필드명], findFirst[숫자]By[필드명] 같은 메소드를 정의해서 사용해봅니다.

  • 리턴 타입
    • 맘대로 넣으면 됩니다. User, List<User>, Optional<User> 외에도 다양한 게 됩니다. Flux였나? 그런 것도 된다네요.
    • 다만 2개 이상이 잡히는 쿼리에서 단순 엔티티(이 경우 User)를 반환하게 한 경우 런타임에 오류가 떨어집니다.
    • 그렇다면 User? 타입이 있는 kotlin 에서는 어떨까요? 이것도 Spring Data JPA가 지원합니다. 다음 섹션의 디펜던시를 추가해서 reflection 을 활성화해줘야 하지만요.
      https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.nullability.kotlin
  • 메서드 이름
    • 메서드 이름을 적절히 만들면 거기에 맞춰서 동작합니다.
      • 예를 들어서, findByName(String name) 으로 메서드를 정의하면 User.name 을 기준으로 일치 여부를 확인해서 줍니다.
      • 메서드 이름의 어딘가에 조건이나 정렬을 추가로 넣을 수도 있는 모양이더라구요.
      • 가독성을 위해 find[아무말] 같은 형태로 원하는 이름을 끼워넣거나, find 대신 get / search 같은 다른 단어를 사용할수도 있습니다. 예를 들자면 findUserByEmail() 이겠죠? 아무말로 끼워넣은 부분은 무시됩니다. findAhZipeGagoShipdaByEmail() 같은 거에서도 무시됩니다.
      • 자세한 규칙은 필요할 때 문서 참조!
    • find 외에도 다영한 메서드가 있지만 delete는 Spring Data JPA 쪽의 함수를 주로 쓰고 해서 find 외에는 잘 안 쓰인다네요.
    • First[갯수] 등으로 처음으로 찾은 것만 조회할 수도 있습니다. findFirst1ByEmail() 같은 방식으로요.
      • Last 는 없습니다. findLast1ByName(String name) 같은 거 짰다간 "Last1" 부분은 깡그리 무시된 상태로 없는 거처럼 동작합니다. 이 부분은 논리적 오류이므로 주의해야겠습니다.

kotlin 에서 Query Method

kotlin 에서 Query Method 를 정의하려고 하면, 리플렉션 없이는 앱이 구동되지 않습니다 (Class Not Found 가 뜨더라구요). 꼭 리플렉션 라이브러리를 추가해놓자구요.

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-reflect:1.6.10"
}

https://kotlinlang.org/docs/reflection.html#jvm-dependency
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.nullability.kotlin

interface UserRepo : JpaRepository<User, Long> {
    fun findByName(name: String): User?
}

그리고, 반환형에 optional 연산자 (? 기호) 가 없으면 엔티티를 못 찾으면 예외가 떨어집니다 (무서워라;).

이런 건 당췌 어떻게 동작하는거야?

런타임에 프록시 객체를 만든다네요. 코드 생성은 없다고... 아래 S/O의 윗문단만 슬쩍 하고 봤습니다. 사실 이 이상은 궁금하지 않기도 해서... (제가 이런 라이브러리를 만들것도 아니고)

https://stackoverflow.com/a/38511337

... there's no code generation ...
... JDK proxy instance is created programmatically ... a MethodInterceptor intercepts all calls to the instance ...
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스: https://bit.ly/37BpXiC

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

실습도 딱히 많이 해볼 필요는 없어보이더라구요. 그냥 물음표 연산자가 지원이 되나 그거만 확인해봤습니다.

오늘은 다른 거도 하고 싶어서 이만 총총 (침대야 내가 간다!!!)
근데 블로그 가독성은 글쓰기 화면이 훨씬 좋던데... 기본 테마라 그릉가 싶기도 하네여