データ]


1前書き

このチュートリアルでは、Spring Data Cassandraのリアクティブデータアクセス機能の使い方を学びます。

特に、これはSpring Data Cassandraの記事シリーズの3番目の記事です。この記事では、REST APIを使用してCassandraデータベースを公開します。

Spring Data Cassandraの詳細については、https://www.baeldung.com/spring-data-cassandra-tutorial[first]およびhttps://www.baeldung.com/spring-data-cassandratemplate-cqltemplate[secondをご覧ください。]シリーズの記事。


2 Mavenの依存関係

実際のところ、Spring Data CassandraはProject ReactorとRxJavaの反応型をサポートしています。例証するために、このチュートリアルではプロジェクトリアクタの反応型

Flux



__Mon

__を使います。

はじめに、チュートリアルに必要な依存関係を追加しましょう。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-cassandra</artifactId>
    <version>2.1.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
</dependency>


__spring-data-cassandra

__の最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework.data%22%20AND%20a%3A%にあります。 22spring-data-cassandra%22[ここ]。

それでは、REST APIを介してデータベースから

SELECT

操作を公開します。それでは、

RestController

の依存関係も追加しましょう。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>


3私たちのアプリを実装する

データを永続化するので、まずエンティティオブジェクトを定義しましょう


_:

_

@Table
public class Employee {
    @PrimaryKey
    private int id;
    private String name;
    private String address;
    private String email;
    private int age;
}

次に、

ReactiveCassandraRepositoryから継承された

__EmployeeRepositoryを作成する時が来ました。

public interface EmployeeRepository extends ReactiveCassandraRepository<Employee, Integer> {
    @AllowFiltering
    Flux<Employee> findByAgeGreaterThan(int age);
}

** 3.1. CRUD操作用の静止コントローラー

説明のために、簡単なRest Controllerを使用して基本的な

SELECT

操作をいくつか公開します。

@RestController
@RequestMapping("employee")
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @PostConstruct
    public void saveEmployees() {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(123, "John Doe", "Delaware", "[email protected]", 31));
        employees.add(new Employee(324, "Adam Smith", "North Carolina", "[email protected]", 43));
        employees.add(new Employee(355, "Kevin Dunner", "Virginia", "[email protected]", 24));
        employees.add(new Employee(643, "Mike Lauren", "New York", "[email protected]", 41));
        employeeService.initializeEmployees(employees);
    }

    @GetMapping("/list")
    public Flux<Employee> getAllEmployees() {
        Flux<Employee> employees = employeeService.getAllEmployees();
        return employees;
    }

    @GetMapping("/{id}")
    public Mono<Employee> getEmployeeById(@PathVariable int id) {
        return employeeService.getEmployeeById(id);
    }

    @GetMapping("/filterByAge/{age}")
    public Flux<Employee> getEmployeesFilterByAge(@PathVariable int age) {
        return employeeService.getEmployeesFilterByAge(age);
    }
}

最後に、簡単な

EmployeeService

を追加しましょう。

@Service
public class EmployeeService {

    @Autowired
    EmployeeRepository employeeRepository;

    public void initializeEmployees(List<Employee> employees) {
        Flux<Employee> savedEmployees = employeeRepository.saveAll(employees);
        savedEmployees.subscribe();
    }

    public Flux<Employee> getAllEmployees() {
        Flux<Employee> employees =  employeeRepository.findAll();
        return employees;
    }

    public Flux<Employee> getEmployeesFilterByAge(int age) {
        return employeeRepository.findByAgeGreaterThan(age);
    }

    public Mono<Employee> getEmployeeById(int id) {
        return employeeRepository.findById(id);
    }
}


3.2. データベース構成

次に、

application.properties

でCassandraとの接続に使用するキースペースとポートを指定しましょう。

spring.data.cassandra.keyspace-name=practice
spring.data.cassandra.port=9042


4エンドポイントのテスト

  • 最後に、APIエンドポイントをテストする時が来ました。**

4.1. 手動テスト

まず、データベースから従業員レコードを取得しましょう。

curl localhost:8080/employee/list

結果として、私たちは全従業員を獲得します。

----[    {
        "id": 324,
        "name": "Adam Smith",
        "address": "North Carolina",
        "email": "[email protected]",
        "age": 43
    },
    {
        "id": 123,
        "name": "John Doe",
        "address": "Delaware",
        "email": "[email protected]",
        "age": 31
    },
    {
        "id": 355,
        "name": "Kevin Dunner",
        "address": "Virginia",
        "email": "[email protected]",
        "age": 24
    },
    {
        "id": 643,
        "name": "Mike Lauren",
        "address": "New York",
        "email": "[email protected]",
       "age": 41
    }]----

続けて、自分のIDで特定の従業員を探しましょう。

curl localhost:8080/employee/643

その結果、Mike Lauren氏を取り戻します。

{
    "id": 643,
    "name": "Mike Lauren",
    "address": "New York",
    "email": "[email protected]",
    "age": 41
}

最後に、年齢フィルタが機能するかどうかを見てみましょう。

curl localhost:8080/employee/filterByAge/35

そして予想どおり、年齢が35歳を超えるすべての従業員を取得します。

----[    {
        "id": 324,
        "name": "Adam Smith",
        "address": "North Carolina",
        "email": "[email protected]",
        "age": 43
    },
    {
        "id": 643,
        "name": "Mike Lauren",
        "address": "New York",
        "email": "[email protected]",
        "age": 41
    }]----

4.2. 統合テスト

さらに、テストケースを書いて同じ機能をテストしましょう。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ReactiveEmployeeRepositoryIntegrationTest {

    @Autowired
    EmployeeRepository repository;

    @Before
    public void setUp() {
        Flux<Employee> deleteAndInsert = repository.deleteAll()
          .thenMany(repository.saveAll(Flux.just(
            new Employee(111, "John Doe", "Delaware", "[email protected]", 31),
            new Employee(222, "Adam Smith", "North Carolina", "[email protected]", 43),
            new Employee(333, "Kevin Dunner", "Virginia", "[email protected]", 24),
            new Employee(444, "Mike Lauren", "New York", "[email protected]", 41))));

        StepVerifier
          .create(deleteAndInsert)
          .expectNextCount(4)
          .verifyComplete();
    }

    @Test
    public void givenRecordsAreInserted__whenDbIsQueried__thenShouldIncludeNewRecords() {
        Mono<Long> saveAndCount = repository.count()
          .doOnNext(System.out::println)
          .thenMany(repository
            .saveAll(Flux.just(
            new Employee(325, "Kim Jones", "Florida", "[email protected]", 42),
            new Employee(654, "Tom Moody", "New Hampshire", "[email protected]", 44))))
          .last()
          .flatMap(v -> repository.count())
          .doOnNext(System.out::println);

        StepVerifier
          .create(saveAndCount)
          .expectNext(6L)
          .verifyComplete();
    }

    @Test
    public void givenAgeForFilter__whenDbIsQueried__thenShouldReturnFilteredRecords() {
        StepVerifier
          .create(repository.findByAgeGreaterThan(35))
          .expectNextCount(2)
          .verifyComplete();
    }
}


5結論

まとめると、Spring Data Cassandraを使用してリアクティブ型を使用してノンブロッキングアプリケーションを構築する方法を学びました。

いつものように、このチュートリアルのソースコードをチェックしてください。