008 R2dbc Query Method

08. R2dbc Query Method #

쿼리 메소드 (Query method) #

  • R2dbcRepository를 상속한 repository interface에 메소드를 추가
  • 메소드의 이름을 기반으로 Query 생성
  • 조회, 삭제 지원
  • @Query 어노테이션을 사용해서 복잡한 쿼리나 update 문도 실행 가능 img.png

쿼리 메소드 - find #

  • id 뿐만 아니라 다른 필드를 이용해서 조회 가능
  • first 등의 키워드를 사용해서 query에 limit 제공 가능
  • 기존의 Entity 뿐만 아니라 Projection을 사용하여 일부 필드만 조회 가능 img_1.png
  • findFirstByNameOrderByAgeDesc
    • name이 “taewoo”인 row들을 찾고
    • age 내림차순으로 sort 하여
    • limit을 1로
    • 모든 field를 조회하여
    • PersonEntity class로 mapping img_2.png img_3.png

쿼리 메소드 - delete #

  • 다른 필드를 이용해서 삭제 가능
    • 여러 반환 타입 지원
    • Integer: 영향을 받은 row 수 반환
    • Boolean: 삭제되었는지 여부 반환
    • Void: 반환값보다는 completion이 중요한 경우 img_4.png
  • deleteByAgeGreaterThan
    • age가 100 초과인 row를 찾고
    • 삭제한 후
    • 영향을 받은 row가 있다면 true를, 없다면 false를 반환 img_5.png img_6.png

쿼리 메서드 시작 키워드 #

  1. find, read, get, query, search, stream
  • find 쿼리를 실행하고 결과를 Publisher으로 반환
  1. exists
  • find exists 쿼리를 실행하고 결과를 Publisher으로 반환
  1. count
  • find count 쿼리를 실행하고 결과를 Publisher으로 반환
  1. delete, remove
  • delete 쿼리를 실행하고 Publisher 혹은 publisher로 삭제된 개수 반환

쿼리 메서드 제한 키워드 #

  1. First, Top
  • 쿼리의 limit을 N으로 설정. find와 By 사이 어디에든 등장 가능
  1. Distinct
  • distinct 기능을 제공. find와 By 사이 어디에든 등장 가능

쿼리 메소드 predicate 키워드 #

  • And: AND
  • Or: OR
  • After, IsAfter: AFTER
  • Before, IsBefore: BEFORE
  • Containing, IsContaining, Contains: CONTAINING
  • Between, IsBetween: BETWEEN
  • EndingWith, IsEndingWith, EndsWith: ENDING_WITH
  • Exists: EXISTS
  • False, IsFalse: FALSE
  • GreaterThan, IsGreaterThan: GREATER_THAN
  • GreaterThanEqual, IsGreaterThanEqual: GREATER_THAN_EQUALS
  • In, IsIn: IN
  • Is, Equals: IS
  • IsEmpty, Empty: IS_EMPTY
  • IsNotEmpty, NotEmpty: IS_NOT_EMPTY
  • NotNull, IsNotNull: IS_NOT_NULL
  • Null, IsNull: IS_NULL
  • LessThan, IsLessThan: LESS_THAN
  • LessThanEqual, IsLessThanEqual: LESS_THAN_EQUAL
  • Like, IsLike: LIKE
  • Near, IsNear: NEAR
  • Not, IsNot: NOT
  • NotIn, IsNotIn: NOT_IN
  • NotLike, IsNotLike: NOT_LIKE
  • Regex, MatchesRegex, Matches: REGEX
  • StartingWith, IsStartingWith, StartsWith: STARTING_WITH
  • True, IsTrue: TRUE
  • Within, IsWithin: WITHIN
  • IgnoreCase, IgnoringCase: 특정 필드에 적용. 비교하려는 대상 모두 UPPER로 만들어서 비교
  • AllIgnoreCase, AllIgnoringCase
  • OrderBy: 주어진 property path와 direction에 따라서 쿼리에 Sort 제공

쿼리 메소드 반환 타입 #

  • Mono
    • Reactor에서 제공
    • 0개 혹은 하나의 값을 반환하는 Publisher
    • 만약 결과가 2개 이상이라면 IncorrectResultSizeDataAccessException 발생
  • Flux
    • Reactor에서 제공
    • 0개 이상의 값을 반환하는 Publisher
    • 끝이 없는 수의 결과를 반환 가능
  • Single
    • RxJava에서 제공
    • 무조건 1개의 값을 반환하는 Publisher
    • 만약 결과가 2개 이상이라면 IncorrectResultSizeDataAccessException 발생
    • 만약 결과가 0개라면 NoSuchElementException 발생
  • Maybe
    • RxJava에서 제공
    • 0개 혹은 하나의 값을 반환하는 Publisher
    • 만약 결과가 2개 이상이라면 IncorrectResultSizeDataAccessException 발생
  • Flowable
    • RxJava에서 제공
    • 0개 이상의 값을 반환하는 Publisher
    • 끝이 없는 수의 결과를 반환 가능

쿼리 메소드 - @Query #

  • query가 메소드 이름으로 전부 표현이 되지 않는 경우
  • 쿼리 메소드 예약어에서 지원되지 않는 문법을 사용하는 경우
  • 복잡한 query문을 사용하는 경우 img_7.png

쿼리 메소드 - @Query #

  • inner join을 이용하여 person_role과 join하여 role이 특정값인 경우에만 조회
  • 결과를 PersonEntity 형태로 반환 img_8.png img_9.png img_10.png

@Transactional #

  • @Transactional를 사용하여 여러 query를 묶어서 진행
  • 새로운 Entity를 만들어서 save하고 update 한 후, findAll을 통해서 모든 row 반환 img_11.png

로그 img_12.png

TransactionalOperator #

  • transactional 메소드를 통해서 주어진 Flux 혹은 Mono를 transaction 안에서 실행 img_13.png

TransactionalOperator 사용 #

  1. flux를 바로 반환하지 않고 transactionalOperator의 transactional로 wrapping 하여 전달 img_15.png

  2. 혹은 execute를 통해서 TransactionCallback 형태로 실행 img_16.png

로그 img_17.png


  1. 강의 : Spring Webflux 완전 정복 : 코루틴부터 리액티브 MSA 프로젝트까지_