1. 概要

Apache Cassandra のDataStaxディストリビューションは、オープンソースのCassandraと互換性のある本番環境に対応した分散データベースです。 監視、改善されたバッチ、ストリーミングデータ処理など、オープンソースディストリビューションでは利用できないいくつかの機能が追加されています。

DataStaxは、ApacheCassandraを配布するためのJavaクライアントも提供します。 このドライバーは高度に調整可能であり、DataStaxディストリビューションのすべての追加機能を利用できますが、オープンソースバージョンとも完全に互換性があります。

このチュートリアルでは、 Apache Cassandra用のDataStaxJavaドライバーを使用してCassandraデータベースに接続し、基本的なデータ操作を実行する方法を説明します。

2. Mavenの依存関係

ApacheCassandra用のDataStaxJavaドライバーを使用するには、クラスパスに含める必要があります。

Mavenでは、java-driver-core依存関係pom.xmlに追加するだけです。

<dependency>
    <groupId>com.datastax.oss</groupId>
    <artifactId>java-driver-core</artifactId>
    <version>4.1.0</version>
</dependency>

<dependency>
    <groupId>com.datastax.oss</groupId>
    <artifactId>java-driver-query-builder</artifactId>
    <version>4.1.0</version>
</dependency>

3. DataStaxドライバーの使用

ドライバーが配置されたので、それを使って何ができるか見てみましょう。

3.1. データベースに接続する

データベースに接続するために、CqlSessionを作成します。

CqlSession session = CqlSession.builder().build();

連絡先を明示的に定義しない場合、ビルダーはデフォルトで 127.0.0.1:9042になります。

CqlSession を構築するために、いくつかの構成可能なパラメーターを使用してコネクター・クラスを作成しましょう。

public class CassandraConnector {

    private CqlSession session;

    public void connect(String node, Integer port, String dataCenter) {
        CqlSessionBuilder builder = CqlSession.builder();
        builder.addContactPoint(new InetSocketAddress(node, port));
        builder.withLocalDatacenter(dataCenter);

        session = builder.build();
    }

    public CqlSession getSession() {
        return this.session;
    }

    public void close() {
        session.close();
    }
}

3.2. キースペースを作成する

データベースへの接続ができたので、キースペースを作成する必要があります。 キースペースを操作するための簡単なリポジトリクラスを作成することから始めましょう。

このチュートリアルでは、レプリカの数を1に設定したSimpleStrategyレプリケーション戦略を使用します。

public class KeyspaceRepository {

    public void createKeyspace(String keyspaceName, int numberOfReplicas) {
        CreateKeyspace createKeyspace = SchemaBuilder.createKeyspace(keyspaceName)
          .ifNotExists()
          .withSimpleStrategy(numberOfReplicas);

        session.execute(createKeyspace.build());
    }

    // ...
}

また、現在のセッションでキースペースの使用を開始できます。

public class KeyspaceRepository {

    //...
 
    public void useKeyspace(String keyspace) {
        session.execute("USE " + CqlIdentifier.fromCql(keyspace));
    }
}

3.3. テーブルの作成

ドライバは、データベースでクエリを構成および実行するためのステートメントを提供します。 たとえば、各ステートメントで個別に使用するキースペースを設定できます

Video モデルを定義し、それを表すテーブルを作成します。

public class Video {
    private UUID id;
    private String title;
    private Instant creationDate;

    // standard getters and setters
}

クエリを実行するキースペースを定義できるように、テーブルを作成しましょう。 ビデオデータを操作するための単純なVideoRepositoryクラスを作成します。

public class VideoRepository {
    private static final String TABLE_NAME = "videos";

    public void createTable() {
        createTable(null);
    }

    public void createTable(String keyspace) {
        CreateTable createTable = SchemaBuilder.createTable(TABLE_NAME)
          .withPartitionKey("video_id", DataTypes.UUID)
          .withColumn("title", DataTypes.TEXT)
          .withColumn("creation_date", DataTypes.TIMESTAMP);

        executeStatement(createTable.build(), keyspace);
    }

    private ResultSet executeStatement(SimpleStatement statement, String keyspace) {
        if (keyspace != null) {
            statement.setKeyspace(CqlIdentifier.fromCql(keyspace));
        }

        return session.execute(statement);
    }

    // ...
}

メソッドcreateTableをオーバーロードしていることに注意してください。

このメソッドのオーバーロードの背後にある考え方は、テーブル作成に2つのオプションを用意することです。

  • 現在使用しているセッションであるキースペースに関係なく、パラメータとしてキースペース名を送信して、特定のキースペースにテーブルを作成します
  • セッションでキースペースの使用を開始し、パラメーターなしでテーブルを作成する方法を使用します。この場合、テーブルはセッションが現在使用しているキースペースに作成されます。

3.4. データを挿入

さらに、ドライバーは準備された制限付きのステートメントを提供します。

PreparedStatement は通常、値のみが変更されて頻繁に実行されるクエリに使用されます。

PreparedStatementに必要な値を入力できます。 その後、BoundStatementを作成して実行します。

データベースにデータを挿入するためのメソッドを書いてみましょう。

public class VideoRepository {

    //...
 
    public UUID insertVideo(Video video, String keyspace) {
        UUID videoId = UUID.randomUUID();

        video.setId(videoId);

        RegularInsert insertInto = QueryBuilder.insertInto(TABLE_NAME)
          .value("video_id", QueryBuilder.bindMarker())
          .value("title", QueryBuilder.bindMarker())
          .value("creation_date", QueryBuilder.bindMarker());

        SimpleStatement insertStatement = insertInto.build();

        if (keyspace != null) {
            insertStatement = insertStatement.setKeyspace(keyspace);
        }

        PreparedStatement preparedStatement = session.prepare(insertStatement);

        BoundStatement statement = preparedStatement.bind()
          .setUuid(0, video.getId())
          .setString(1, video.getTitle())
          .setInstant(2, video.getCreationDate());

        session.execute(statement);

        return videoId;
    }

    // ...
}

3.5. データのクエリ

次に、データベースに保存したデータを取得するための簡単なクエリを作成するメソッドを追加しましょう。

public class VideoRepository {
 
    // ...
 
    public List<Video> selectAll(String keyspace) {
        Select select = QueryBuilder.selectFrom(TABLE_NAME).all();

        ResultSet resultSet = executeStatement(select.build(), keyspace);

        List<Video> result = new ArrayList<>();

        resultSet.forEach(x -> result.add(
            new Video(x.getUuid("video_id"), x.getString("title"), x.getInstant("creation_date"))
        ));

        return result;
    }

    // ...
}

3.6. すべてを一緒に入れて

最後に、このチュートリアルで説明した各セクションを使用した例を見てみましょう。

public class Application {
 
    public void run() {
        CassandraConnector connector = new CassandraConnector();
        connector.connect("127.0.0.1", 9042, "datacenter1");
        CqlSession session = connector.getSession();

        KeyspaceRepository keyspaceRepository = new KeyspaceRepository(session);

        keyspaceRepository.createKeyspace("testKeyspace", 1);
        keyspaceRepository.useKeyspace("testKeyspace");

        VideoRepository videoRepository = new VideoRepository(session);

        videoRepository.createTable();

        videoRepository.insertVideo(new Video("Video Title 1", Instant.now()));
        videoRepository.insertVideo(new Video("Video Title 2",
          Instant.now().minus(1, ChronoUnit.DAYS)));

        List<Video> videos = videoRepository.selectAll();

        videos.forEach(x -> LOG.info(x.toString()));

        connector.close();
    }
}

この例を実行した後、結果として、データがデータベースに適切に保存されていることがログで確認できます。

INFO com.baeldung.datastax.cassandra.Application - [id:733249eb-914c-4153-8698-4f58992c4ad4, title:Video Title 1, creationDate: 2019-07-10T19:43:35.112Z]
INFO com.baeldung.datastax.cassandra.Application - [id:a6568236-77d7-42f2-a35a-b4c79afabccf, title:Video Title 2, creationDate: 2019-07-09T19:43:35.181Z]

4. 結論

このチュートリアルでは、ApacheCassandra用のDataStaxJavaドライバーの基本的な概念について説明しました。 データベースに接続し、キースペースとテーブルを作成しました。 また、テーブルにデータを挿入し、クエリを実行してデータを取得しました。

いつものように、このチュートリアルのソースコードは、Githubから入手できます。