1. 소개
R2DBC (Reactive Relational Database Connectivity)는 Spring One Platform 2018에서 Pivotal이 발표한 노력입니다. SQL 데이터베이스에 대한 반응형 API를 만들려고 합니다.
2. 첫 번째 Spring Data R2DBC 프로젝트
우선, R2DBC 프로젝트는 매우 최근의 프로젝트입니다. 현재 PostGres, MSSQL 및 H2에만 R2DBC 드라이버가 있습니다. 또한 모든 Spring Boot 기능 을 사용할 수 없습니다. 따라서 수동으로 추가해야 하는 몇 가지 단계가 있습니다. 그러나 Spring Data 와 같은 프로젝트를 활용 하여 도움을 받을 수 있습니다.
먼저 Maven 프로젝트를 생성합니다. 이 시점에서 R2DBC에는 몇 가지 의존성 문제가 있으므로 pom.xml 이 평소보다 커집니다.
이 기사의 범위에서는 H2 를 데이터베이스로 사용하고 애플리케이션을 위한 반응형 CRUD 기능을 생성합니다.
생성된 프로젝트의 pom.xml 을 열고 적절한 의존성과 일부 초기 릴리스 Spring 리포지토리를 추가해 보겠습니다.
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-r2dbc</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<version>0.8.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
</dependencies>
기타 필요한 아티팩트에는 Lombok, Spring WebFlux 및 프로젝트 의존성 을 완료하는 몇 가지 기타 항목이 포함됩니다 .
3. 연결 Factory
데이터베이스로 작업할 때 연결 팩토리가 필요합니다. 물론 R2DBC에도 같은 것이 필요합니다.
이제 인스턴스에 연결하기 위한 세부 정보를 추가합니다.
@Configuration
@EnableR2dbcRepositories
class R2DBCConfiguration extends AbstractR2dbcConfiguration {
@Bean
public H2ConnectionFactory connectionFactory() {
return new H2ConnectionFactory(
H2ConnectionConfiguration.builder()
.url("mem:testdb;DB_CLOSE_DELAY=-1;")
.username("sa")
.build()
);
}
}
위의 코드에서 가장 먼저 눈에 띄는 것은 @EnableR2dbcRepositories 입니다. Spring Data 기능을 사용하려면 이 어노테이션이 필요합니다. 또한 AbstractR2dbcConfiguration 은 나중에 필요한 많은 bean을 제공하므로 확장하고 있습니다.
4. 첫 번째 R2DBC 애플리케이션
다음 단계는 저장소를 만드는 것입니다.
interface PlayerRepository extends ReactiveCrudRepository<Player, Integer> {}
ReactiveCrudRepository 인터페이스 는 매우 유용합니다. 예를 들어 기본 CRUD 기능을 제공합니다.
마지막으로 모델 클래스를 정의합니다. 상용구 코드를 피하기 위해 Lombok을 사용합니다.
@Data
@NoArgsConstructor
@AllArgsConstructor
class Player {
@Id
Integer id;
String name;
Integer age;
}
5. 테스트
코드 를 테스트 할 시간 입니다. 이제 몇 가지 테스트 사례를 만들어 보겠습니다.
@Test
public void whenDeleteAll_then0IsExpected() {
playerRepository.deleteAll()
.as(StepVerifier::create)
.expectNextCount(0)
.verifyComplete();
}
@Test
public void whenInsert6_then6AreExpected() {
insertPlayers();
playerRepository.findAll()
.as(StepVerifier::create)
.expectNextCount(6)
.verifyComplete();
}
6. Custom 검색어
사용자 정의 쿼리를 생성할 수도 있습니다 . 추가하려면 PlayerRepository 를 변경해야 합니다 .
@Query("select id, name, age from player where name = $1")
Flux<Player> findAllByName(String name);
@Query("select * from player where age = $1")
Flux<Player> findByAge(int age);
기존 테스트 외에도 최근 업데이트된 리포지토리에 테스트를 추가합니다.
@Test
public void whenSearchForCR7_then1IsExpected() {
insertPlayers();
playerRepository.findAllByName("CR7")
.as(StepVerifier::create)
.expectNextCount(1)
.verifyComplete();
}
@Test
public void whenSearchFor32YearsOld_then2AreExpected() {
insertPlayers();
playerRepository.findByAge(32)
.as(StepVerifier::create)
.expectNextCount(2)
.verifyComplete();
}
private void insertPlayers() {
List<Player> players = Arrays.asList(
new Player(1, "Kaka", 37),
new Player(2, "Messi", 32),
new Player(3, "Mbappé", 20),
new Player(4, "CR7", 34),
new Player(5, "Lewandowski", 30),
new Player(6, "Cavani", 32)
);
playerRepository.saveAll(players).subscribe();
}
7. 배치
R2DBC의 또 다른 기능은 배치를 생성하는 것입니다. 배치는 개별 작업보다 더 잘 수행되므로 여러 SQL 문을 실행할 때 유용합니다.
Batch 를 만들려면 연결 개체 가 필요 합니다.
Batch batch = connection.createBatch();
애플리케이션이 Batch 인스턴스를 생성한 후 원하는 만큼 SQL 문을 추가할 수 있습니다. 이를 실행하기 위해 execute() 메서드를 호출합니다. 일괄 처리의 결과는 각 문에 대한 결과 개체를 반환하는 게시자 입니다.
이제 코드로 이동하여 Batch 를 만드는 방법을 살펴보겠습니다 .
@Test
public void whenBatchHas2Operations_then2AreExpected() {
Mono.from(factory.create())
.flatMapMany(connection -> Flux.from(connection
.createBatch()
.add("select * from player")
.add("select * from player")
.execute()))
.as(StepVerifier::create)
.expectNextCount(2)
.verifyComplete();
}
8. 결론
요약하면 R2DBC는 아직 초기 단계입니다. SQL 데이터베이스에 대한 반응형 API를 정의하는 SPI를 생성하려는 시도입니다. Spring WebFlux 와 함께 사용하면 R2DBC를 사용하여 위쪽에서 데이터베이스까지 데이터를 비동기식으로 처리하는 애플리케이션을 작성할 수 있습니다.
항상 그렇듯이 코드는 GitHub 에서 사용할 수 있습니다 .
즉, 이러한 노력은 완전한 비차단 드라이버를 사용하여 데이터베이스 연결을 생성합니다.
이 예제에서는 Spring Data R2BDC를 사용하는 애플리케이션의 예를 살펴보겠습니다. 더 낮은 수준의 R2DBC API에 대한 사용방법(예제)는 이전 기사 를 참조하십시오 .