Spring WebFlux를 이용해서 Reactive를 구현했지만, DB가 Reactive하지 않고 막혀버린다면 Reactive하다고 할 수 없다.
스프링 데이터 리액티브
스프링 데이터는 몽고DB(MongoDB), 카산드라(Cassandra), 레디스(Redis), 카우치베이스(Couchbase)로 데이터를 저장할 때 Reactive 프로그래밍 모델을 지원한다.
RDBMS, JPA는 리액티브 Repository가 지원되지 않는데, JDBC 드라이버도 블로킹 되지 않아야 하는데 그게 안 되기 때문이다.
하지만! DB가 리액티브가 아니어도 데이터를 가져와 리액티브 타입으로 변환하는 식으로 사용할 수 있다.
1.
// 데이터를 가져와서 리액티브로 변환
List<Member> members = repo.findByGender("male");
FLux<Member> memberFlux = Flux.fromIterable(members);
// 리액티브를 받아서 데이터 조작
// cart는 장바구니 개념이라고 가정해 봄
Iterable<Cart> cart = cartFlux.toIterable();
// 위는 Flux<cart>를 Iterable로 변환. 변환하면서 block()을 함.
cartRepository.saveAll(cart) // 카트 내역을 저장시킴
위의 코드들은 리액티브하다고 할 수도 없고 아니라고 할 수도 없다.따라서 Mono또는 Flux는 자제해야 한다.
블로킹되는 연산을 조금이라도 피하려면 Mono나 Flux를 구독(Subscribe)하면서 발행되는 요소 각각에 대해 연산을 수행하면 된다.
2.
// cart는 장바구니 개념
cartFlux.subscribe(cart->{
cartRepository.save(cart);
});
둘 다 여전히 블락을 하지만, 1의 saveAll처럼 일괄적으로 하는 처리보다는 2번의 구독 시점에서 처리하는게 바람직하다.
몽고DB 리액티브 레포지토리 작성
몽고DB는 유명한 NoSQL DB 중 하나이며 문서형 DB다.
도메인 타입을 문서 구조로 Mapping하는 어노테이션을 도메인 클래스에 지정하고, 레포지토리 인터페이스를 작성하면 된다.
순서대로 알아보자
1. 몽고DB 활성화
<!-- 일반 몽고DB를 사용할 때 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!-- 리액티브로 몽고DB를 사용할 때 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
리액티브를 알아볼 것이기 때문에 data-mongodb-reactive의 의존성을 추가한다.
2. 몽고DB Properties 추가
spring:
data:
mongodb:
host: mongodb.서버호스트주소
port: 27018 --기본 값
username: db사용자이름
password: db사용자비번
3. 도메인(domain) 타입을 매핑
- @Id : 문서 ID로 지정
- @Document : 몽고DB에 저장되는 문서로 선언
- @Field : 필드 이름을 지정
@Data
@RequiredArgsConstructor
@NoArgsConstructor(access=AccessLevel.PRIVATE,force=true)
@Document
//@Document(collection="meeeember") 라고 쓰면 meeeember라는 이름으로 컬렉션이 만들어짐
public class Member {
@Id
private final String id;
private final String pw;
}
4. 리액티브로 레포지토리 인터페이스 작성
@CrossOrigin(origins="*")
public interface ProductRepository
extends ReactiveMongoRepository<Product, String> {
Flux<Product> jpa메소드이름();
}
Reactive Repository를 만들기 위해서
ReactiveCrudRepository 또는 ReactiveMongoRepository 중 하나를 선택할 수 있다.
- ReactiveCrudRepository : 새로운 문서 or 기존 문서의 save에 의존
- ReactiveMongoRepository : 새로운 문서의 저장에 최적화
쉽게 말해서 고정된 값이 많고 변동사항이 없다면 Crud를 사용하고,
변동 사항이 많다면 Mongo를 사용하도록 한다.
'Spring' 카테고리의 다른 글
Spring boot MongoDB Aggregation에서 sum 조건 정하기 (0) | 2023.04.19 |
---|---|
Spring에서 인터페이스를 사용하는 프로그래밍(programming to interface)이 좋은 이유 (0) | 2022.09.04 |
Spring에서 REST (0) | 2022.04.02 |
JPA(Java Persistence Api) 사용하기 (0) | 2022.03.26 |
Spring Boot 폼 입력 유효성 검사(Form Validation ) (0) | 2022.03.24 |