Spring Data R2DBC는 Spring Data 프로젝트의 일부로 R2DBC 표준을 기반으로 관계형 데이터베이스와의 상호작용을 위한 리액티브 프로그래밍 모델을 제공한다.
기존의 Spring Data JPA나 Spring Data JDBC가 블로킹 방식이었다면, Spring Data R2DBC는 비동기적이고 논블로킹 방식으로 데이터베이스 작업을 처리하여 리액티브 스택과의 완벽한 통합을 목표로 한다.
Repository추상화를 그대로 활용한다.ReactiveCrudRepository, ReactiveSortingRepository와 같은 인터페이스를 통해 기본적인 CRUD 및 정렬 기능을 리액티브하게 제공한다.findByLoginId, findById 등R2dbcEntityTemplate을 제공하여 저수준의 R2DBC API를 직접 다룰 필요 없이 SQL 쿼리를 실행하거나 엔티티를 매핑하는 데 사용할 수 있다.Mono, Flux 등의 반응형 타입과 subscribe(), map(), flatMap() 등의 연산자에 대한 이해가 필수적이다.@Transactional 애노테이션은 사용할 수 있지만, TransactionalOperator와 같은 리액티브 트랜잭션 API를 이해하는 것이 좋다.R2dbcEntityTemplate를 사용하여 직접 SQL을 작성해야 할 수도 있다.// 1. 엔티티 정의
@Data // Lombok
@Table("users") // 데이터베이스 테이블 매핑
public class User {
@Id // 기본 키
private Long id;
private String loginId;
private String password;
private int age;
}
// 2. 리포지토리 인터페이스 정의
public interface UserRepository extends ReactiveCrudRepository<User, Long> {
// 메서드 이름으로 쿼리 자동 생성 (예: SELECT * FROM users WHERE first_name = ? AND last_name = ?)
Flux<User> findByLoginId(String loginId);
// 나이가 특정 값보다 큰 사용자 찾기
Flux<User> findByAgeGreaterThan(int age);
}
// 3. 서비스 계층에서 사용
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Flux<User> findAllUsers() {
return userRepository.findAll();
}
public Mono<User> findUserById(Long id) {
return userRepository.findById(id);
}
public Mono<User> saveUser(User user) {
return userRepository.save(user);
}
public Mono<Void> deleteUserById(Long id) {
return userRepository.deleteById(id);
}
public Flux<User> findUserByLoginId(String loginId) {
return userRepository.findByLoginId(loginId);
}
}