아래는 **"스프링부트 웹플럭스 시리즈"**의 **6장: 리액티브 데이터베이스 연동"**에 대한 초안입니다. MariaDB를 예시로 사용하며, R2DBC를 통해 리액티브 방식으로 연동합니다. 설정은 `application.yaml`을 사용하고, 간단한 실습 코드를 포함했습니다. 초보자도 따라 할 수 있도록 단계별로 설명하며 친근한 문체를 유지했습니다.

---

## 6. 리액티브 데이터베이스 연동

이제 웹플럭스의 리액티브 특성을 데이터베이스와 연결해볼 시간입니다. 이번 장에서는 MariaDB를 리액티브하게 다루는 방법을 배워보겠습니다. 전통적인 JDBC 대신 R2DBC(Reactive Relational Database Connectivity)를 사용하며, 설정은 `application.yaml`로 깔끔하게 정리하겠습니다. 데이터 조회와 저장 예제도 함께 해보며 실습을 진행할게요. 준비되셨죠?

### R2DBC와 리액티브 리포지토리 설정

R2DBC는 관계형 데이터베이스를 비동기/논블로킹 방식으로 접근하게 해주는 드라이버입니다. 웹플럭스와 찰떡궁합이죠. 먼저, MariaDB와 R2DBC를 사용하기 위해 Gradle에 의존성을 추가합니다. `build.gradle`에 아래를 추가하세요:

```gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
    implementation 'io.r2dbc:r2dbc-mariadb:1.1.3'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
}
```

- `spring-boot-starter-data-r2dbc`: R2DBC와 스프링 데이터 통합을 위한 스타터.
- `r2dbc-mariadb`: MariaDB용 R2DBC 드라이버.

의존성을 추가한 뒤, `./gradlew build`로 빌드해줍니다.

다음으로, `application.yaml`을 설정합니다. `src/main/resources`에 `application.yaml` 파일을 만들고 아래 내용을 입력하세요:

```yaml
spring:
  r2dbc:
    url: r2dbc:mariadb://localhost:3306/webflux_db
    username: root
    password: yourpassword
  data:
    r2dbc:
      repositories:
        enabled: true
```

- `url`: MariaDB 데이터베이스 연결 정보 (예: `webflux_db`라는 데이터베이스 사용).
- `username`, `password`: MariaDB 접속 계정 정보 (환경에 맞게 수정하세요).

MariaDB에 `webflux_db` 데이터베이스를 미리 만들어야 합니다. MariaDB 클라이언트에서 다음 명령어를 실행하세요:

```sql
CREATE DATABASE webflux_db;
```

### MariaDB와의 연동 예제

이제 간단한 사용자(User) 데이터를 저장하고 조회하는 예제를 만들어보겠습니다. 먼저, 테이블을 생성합니다. MariaDB에서 아래 SQL을 실행하세요:

```sql
USE webflux_db;
CREATE TABLE users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);
```

#### 엔티티 클래스 작성

`src/main/java/com/example/demo`에 `User` 클래스를 추가합니다:

```java
package com.example.demo;

import lombok.Data;
import org.springframework.data.annotation.Id;

@Data
public class User {
    @Id
    private Long id;
    private String name;
    private String email;
}
```

- `@Id`: 기본 키를 나타냅니다.
- `@Data`: Lombok으로 getter/setter 등을 자동 생성.

#### 리포지토리 인터페이스 생성

`src/main/java/com/example/demo`에 `UserRepository` 인터페이스를 만듭니다:

```java
package com.example.demo;

import org.springframework.data.r2dbc.repository.R2dbcRepository;
import reactor.core.publisher.Mono;

public interface UserRepository extends R2dbcRepository<User, Long> {
    Mono<User> findByEmail(String email);
}
```

- `R2dbcRepository`: 리액티브 CRUD 작업을 지원.
- `findByEmail`: 이메일로 사용자 조회 메서드 추가.

#### 데이터 저장 및 조회 실습

컨트롤러를 만들어 데이터를 다뤄봅시다. `src/main/java/com/example/demo`에 `UserController`를 추가합니다:

```java
package com.example.demo;

import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/users")
public class UserController {

    private final UserRepository userRepository;

    public UserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @PostMapping
    public Mono<User> createUser(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping("/{id}")
    public Mono<User> getUserById(@PathVariable Long id) {
        return userRepository.findById(id);
    }

    @GetMapping("/email/{email}")
    public Mono<User> getUserByEmail(@PathVariable String email) {
        return userRepository.findByEmail(email);
    }

    @GetMapping
    public Flux<User> getAllUsers() {
        return userRepository.findAll();
    }
}
```

- `createUser`: 새 사용자를 저장.
- `getUserById`: ID로 사용자 조회.
- `getUserByEmail`: 이메일로 사용자 조회.
- `getAllUsers`: 모든 사용자 목록 반환.

#### 테스트해보기

애플리케이션을 실행한 뒤, Postman이나 curl로 테스트해봅시다.

1. **사용자 추가**:
   ```
   POST http://localhost:8080/users
   Content-Type: application/json
   {"name": "Alice", "email": "alice@example.com"}
   ```
   응답으로 저장된 사용자 객체가 반환됩니다.

2. **사용자 조회 (ID)**:
   ```
   GET http://localhost:8080/users/1
   ```
   ID가 1인 사용자가 반환됩니다.

3. **사용자 조회 (이메일)**:
   ```
   GET http://localhost:8080/users/email/alice@example.com
   ```
   이메일로 조회한 결과가 나옵니다.

4. **모든 사용자 조회**:
   ```
   GET http://localhost:8080/users
   ```
   저장된 모든 사용자가 리스트로 표시됩니다.

### 잠깐 정리

- **R2DBC**: MariaDB를 리액티브하게 연결.
- **`application.yaml`**: 간단한 설정으로 데이터베이스 연결 완료.
- **리포지토리**: 비동기 CRUD 작업을 쉽게 처리.

이 과정에서 `Mono`와 `Flux`가 데이터베이스 작업에 자연스럽게 녹아든 걸 느끼셨을 겁니다. 전통적인 JDBC와 달리 스레드가 블록되지 않아 더 많은 요청을 효율적으로 처리할 수 있죠.

### 마무리

MariaDB와의 리액티브 연동을 성공적으로 해냈습니다! 데이터베이스 작업이 웹플럭스의 비동기 흐름과 어떻게 맞물리는지 실감 나셨나요? 다음 장에서는 이 데이터를 기반으로 REST API를 설계하며, 실무에서 더 유용한 기능을 추가해보겠습니다. 이번 실습이 재미있으셨길 바랍니다!

---

이 장은 MariaDB와 R2DBC를 활용한 실습 중심으로 구성했으며, `application.yaml` 설정과 간단한 코드를 포함했습니다. 추가 예제나 수정이 필요하면 말씀해주세요!