Spring/스프링으로 시작하는 리액티브 프로그래밍

Spring Data R2DBC 간단 정리

꾸준함. 2024. 9. 11. 19:17

R2DBC (Reactive Relational Database Connectivity)

  • 관계형 데이터베이스에 리액티브 프로그래밍 API를 제공하기 위한 개방형 사양(Specification)
  • 드라이버 벤더가 구현하고 클라이언트가 사용하기 위한 SPI(Service Provider Interface)
  • R2DBC의 등장으로 관계형 데이터베이스를 사용하더라도 클라이언트의 요청부터 데이터베이스 접근까지 완전한 non-blocking 애플리케이션을 구현하는 것이 가능해짐

 

1. R2DBC를 지원하는 드라이버 목록

  • ClilckHouse R2DBC Driver
  • Google Cloud Spanner
  • Jasync-sql MySQL
  • Oracle R2DBC Driver
  • R2DBC H2
  • R2DBC MariaDB
  • R2DBC MySQL
  • R2DBC PostgreSQL
  • R2DBC Proxy
  • R2DBC SQL Server

 

참고 문헌: https://r2dbc.io/

 

R2DBC

R2DBC 0.8.1.RELEASE: A standard API for reactive programming using SQL databases.

r2dbc.io

 

Spring Data R2DBC

  • R2DBC 기반 Repository를 좀 더 쉽게 구현하게 해주는 Spring Data Family 프로젝트의 일부
  • Spring이 추구하는 추상화 기법이 적용되어 Spring Data JDBC나 Spring Data JPA 같은 Spring Data Family 계열의 기술을 사용해 보았다면 Spring Data R2DBC의 API 사용법 역시 친숙하게 느껴짐
    • JPA 같은 ORM 프레임워크에서 제공하는 caching, lazy loading, 기타 ORM 프레임워크에서 가지고 있는 특징들이 제거되어 단순한 방법으로 사용 가능
    • 여타 Spring Data Family 프로젝트와 마찬가지로 Spring Data R2DBC를 통해 데이터 액세스 계층의 보일러플레이트 코드의 양을 대폭 줄임

 

1. Spring Data R2DBC 설정 (h2 기준)

 

1.1 pom.xml 설정

 

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-r2dbc -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-r2dbc</artifactId>
    <version>3.3.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.r2dbc/r2dbc-h2 -->
<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-h2</artifactId>
    <version>1.0.0.RELEASE</version>
</dependency>

 

1.2 schema.sql, data.sql 및 application.yml 설정

  • Spring Data R2DBC는 Spring Data JPA처럼 엔티티에 정의된 매핑 정보로 테이블을 자동으로 생성해주는 기능이 없기 때문에 테이블 스크립트를 직접 작성해서 테이블을 생성해야 함
    • 따라서 resource 폴더 하위에 schema.sql과 함께 초기 데이터 필요시 data.sql 파일 생성 후 application.yml에서 프로젝트 기동 시 파일 내용을 DB 내용에 반영하도록 설정 필요


 

1.3 R2DBC Repository와 Auditing 기능 활성화

  • R2DBC용 Repository와 Auditing 기능 활성화를 위해 @EnableR2dbcRepositories와 @EnableR2dbcAuditing 추가 필요

 

 

2. 도메인 엔티티 클래스 매핑

  • Spring Data JPA의 Entity와 비슷하지만 아쉽게도 @XToX와 같은 어노테이션을 지원하지 않아 외래키 설정 불가
  • Spring Data R2DBC에서 제공하는 매핑 어노테이션
    • @Id: 데이터베이스 테이블의 Primary Key로 지정
    • @Table: 클래스를 특정 데이터베이스 테이블과 매핑
    • @Transient: 해당 어노테이션이 붙은 필드는 데이터베이스에 저장되지 않으며 데이터베이스와의 매핑에서 제외시킴
    • @PersistenceCreator: R2DBC에서 엔티티 생성자를 지정할 때 사용하며 여러 생성자 중 엔티티를 영속성 컨텍스트에 로드할 때 사용할 생성자 명시
    • @Value: 기본 값으로 설정하거나 속성 주입 방식으로 사용할 때 사용
    • @Column: 클래스의 필드를 데이터베이스 테이블의 특정 열에 매핑
    • @Version: Optimistic Locking을 구현할 때 사용
    • @CreatedDate: 생성 일시 자동으로 테이블에 반영
    • @LastModifiedDate: 수정 일시 자동으로 테이블에 반영

 

참고 문헌: https://docs.spring.io/spring-data/relational/reference/r2dbc/mapping.html

 

Mapping :: Spring Data Relational

To take full advantage of the object mapping functionality inside the Spring Data R2DBC support, you should annotate your mapped objects with the @Table annotation. Although it is not necessary for the mapping framework to have this annotation (your POJOs

docs.spring.io

 

3. ReactiveCrudRepository

  • Spring Data R2DBC에서 제공하는 리액티브 프로그래밍 모델을 지원하는 인터페이스로 비동기적이고 non-blocking 방식으로 데이터베이스와 상호작용할 수 있도록 지원
  • Mono와 Flux 같은 리액티브 타입을 반환하며 데이터베이스에서의 작업이 완료될 때 비동기적으로 결과를 처리

 

3.1 ReactiveCrudRepository vs JpaRepository

 

항목 ReactiveCrudRepository JpaRepository
프로그래밍 모델 non-blocking, 비동기 동기적 blocking 방식
반환 타입 Mono<T>, Flux<T> Optional<T>, List<T>
ORM 지원 여부 X JPA 기반의 ORM 제공
트랜잭션 관리 수동으로 관리 필요
트랜잭션 지원이 제한적
자동 트랜잭션 관리 지원
대상 DB R2DBC 지원하는 데이터베이스 JPA를 지원하는 전통적인 RDB

 

4. R2dbcEntityTemplate

  • 템플릿/콜백 패턴이 적용된 JdbcTemplate처럼 R2dbcEntityTemplate 역시 템플릿을 사용
    • JdbcTemplate은 SQL 쿼리를 직접적으로 템플릿에 전달
    • R2dbcEntityTemplate은 JPA 기술에 사용되는 QueryDSL과 유사한 방식의 쿼리 생성 메서드의 조합과 Entity 객체를 템플릿에 전달하여 데이터베이스와 상호 작용

 

  • R2dbcEntityTemplate은 SQL 쿼리문의 시작 구문인 SELECT, INSERT, UDATE, DELETE 등에 해당하는 select(), insert(), update(), delete() 메서드인 Entrypoint Method를 지원
  • all(), count(), one() 등의 메서드처럼 SQL 문을 생성하고 최종적으로 SQL 문을 실행하는 메서드인 Terminating Method를 지원
  • 또한, R2dbcEntityTemplate은 SQL 연산자에 해당하는 다양한 Criteria Method를 지원

 

4.1 Terminating Method

 

메서드 설명
first() 조건에 일치하는 result row 중에서 first row를 얻고자 할 경우 사용
만약 조건에 일치하는 row가 없다면 Mono<Void>를 반환
one() 조건에 일치하는 result row가 단 하나일 경우 사용
만약 조건에 일치하는 row가 없다면 Mono<Void>를 반환
result row가 한 건보다 많을 경우 Exception 발생
all() 조건에 일치하는 모든 result row를 얻고자 할 경우 사용
count() 조건에 일치하는 데이터의 건수만 조회할 경우 사용
반환 타입은 Mono<Long>
exists() 조건에 일치하는 result row가 존재하는지 여부를 확인하고자 할 경우 사용
반환 타입은 Mono<Boolean>

 

4.2 Criteria Method

 

메서드 설명
and(String column) SQL 쿼리문에서 and 연산자에 해당
파라미터로 주어지는 컬럼명에 해당하는 Criteria를 추가한 새로운 Criteria 반환
or(String column) SQL 쿼리문에서 or 연산자에 해당
파라미터로 주어지는 컬럼명에 해당하는 Criteria를 추가한 새로운 Criteria 반환
greaterThan(Object o) SQL 쿼리문에서 '>; 연산자에 해당
'greater-than' Criteria를 추가한 새로운 Criteria 반환
greaterThanOrEquals(Object o) SQL 쿼리문에서 '>=' 연산자에 해당
'greater-than or equal to' Criteria를 추가한 새로운 Criteria 반환
in(Object... o)
in(Collection<?> collection)
SQL 쿼리문에서 'IN' 연산자에 해당하는 Criteria를 추가한 새로운 Criteria 반환
is(Object o) SQL 쿼리문에서 '=' 연산자에 해당하는 Criteria를 추가한 새로운 Criteria 반환
isNull() SQL 쿼리문에서 'IS NULL' 연산자에 해당되는 Criteria를 추가한 새로운 Criteria 반환
isNotNull() SQL 쿼리문에서 'IS NOT NULL' 연산자에 해당되는 Criteria를 추가한 새로운 Criteria 반환
lessThan(Object o) SQL 쿼리문에서 '<' 연산자에 해당되며, 'less-than' Criteria를 추가한 새로운 Criteria 반환
lessThanOrEquals(Object o) SQL 쿼리문에서 '<=' 연산자에 해당되며, 'less-than or equal to' Criteria를 추가한 새로운 Criteria 반환
like(Object o) SQL 쿼리문에서 'LIKE' 연산자에 해당되는 Criteria를 추가한 새로운 Criteria 반환
not(Object o) SQL 쿼리문에서 '!=' 또는 'NOT' 연산자에 해당되는 Criteria를 추가한 새로운 Criteria 반환
notIn(Object... o)
notIn(Collection<?> collection)
SQL 쿼리문에서 'NOT IN' 연산자에 해당되는 Criteria를 추가한 새로운 Criteria 반환

 

5. Spring Data R2DBC Pagination

  • 다른 Spring Data 패밀리 프로젝트에서의 페이지네이션 처리와 유사
  • Spring Data 패밀리 프로젝트에서 사용하는 Pageable을 이용해서 페이지네이션을 적용하는 방법은 동일하지만 반환 타입이 List<T>가 아니라 Flux<T>라는 차이점 존재

 

참고

  • 스프링으로 시작하는 리액티브 프로그래밍 (황정식 저자)
반응형