Intro to DataStax Java Driver for Apache Cassandra – Apache Cassandra的DataStax Java驱动介绍

最后修改: 2019年 9月 7日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The DataStax Distribution of Apache Cassandra is a production-ready distributed database, compatible with open-source Cassandra. It adds a few features that aren’t available in the open-source distribution, including monitoring, improved batch, and streaming data processing.

Apache Cassandra 的 DataStax 分发版是一个生产就绪的分布式数据库,与开源的 Cassandra 兼容。它增加了一些开源发行版中没有的功能,包括监控、改进的批处理和流式数据处理。

DataStax also provides a Java client for its distribution of Apache Cassandra. This driver is highly tunable and can take advantage of all the extra features in the DataStax distribution, yet it’s fully compatible with the open-source version, too.

DataStax还为其发行的Apache Cassandra提供了一个Java客户端。这个驱动是高度可调的,可以利用DataStax发行版中的所有额外功能,但它也与开源版本完全兼容。

In this tutorial, we’ll see how to use the DataStax Java Driver for Apache Cassandra to connect to a Cassandra database and perform basic data manipulation.

在本教程中,我们将看到如何使用DataStax Java Driver for Apache Cassandra连接到 Cassandra 数据库并执行基本数据操作。

2. Maven Dependency

2.Maven的依赖性

In order to use the DataStax Java Driver for Apache Cassandra, we need to include it in our classpath.

为了使用DataStax Java Driver for Apache Cassandra,我们需要将其纳入我们的classpath。

With Maven, we simply have to add the java-driver-core dependency to our pom.xml:

使用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. Using the DataStax Driver

3.使用DataStax驱动程序

Now that we have the driver in place, let’s see what we can do with it.

现在我们已经有了驱动程序,让我们看看我们能用它做什么。

3.1. Connect to the Database

3.1.连接到数据库

In order to get connected to the database, we’ll create a CqlSession:

为了获得与数据库的连接,我们将创建一个CqlSession

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

If we don’t explicitly define any contact point, the builder will default to 127.0.0.1:9042.

如果我们没有明确定义任何联系点,构建器将默认为127.0.0.1:9042

Let’s create a connector class, with some configurable parameters, to build the CqlSession:

让我们创建一个连接器类,用一些可配置的参数,来构建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. Create Keyspace

3.2.创建钥匙空间

Now that we have a connection to the database, we need to create our keyspace. Let’s start by writing a simple repository class for working with our keyspace.

现在我们有了一个与数据库的连接,我们需要创建我们的钥匙空间。让我们先写一个简单的存储库类来处理我们的钥匙空间。

For this tutorial, we’ll use the SimpleStrategy replication strategy with the number of replicas set to 1:

在本教程中,我们将使用SimpleStrategy复制策略,复制的数量设置为1

public class KeyspaceRepository {

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

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

    // ...
}

Also, we can start using the keyspace in the current session:

另外,我们可以开始使用当前会话中的密钥空间

public class KeyspaceRepository {

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

3.3. Create Table

3.3.创建表格

The driver provides statements to configure and execute queries in the database. For example, we can set the keyspace to use individually in each statement.

驱动程序提供了在数据库中配置和执行查询的语句。例如,我们可以在每个语句中单独设置要使用的密钥空间

We’ll define the Video model and create a table to represent it:

我们将定义视频模型并创建一个表来表示它。

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

    // standard getters and setters
}

Let’s create our table, having the possibility to define the keyspace in which we want to perform the query. We’ll write a simple VideoRepository class for working with our video data:

让我们创建我们的表,有可能定义我们想要执行查询的关键空间。我们将写一个简单的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);
    }

    // ...
}

Note that we’re overloading the method createTable.

注意,我们正在重载createTable方法。

The idea behind overloading this method is to have two options for the table creation:

重载这个方法的想法是为创建表提供两种选择。

  • Create the table in a specific keyspace, sending keyspace name as the parameter, independently of which keyspace is the session currently using
  • Start using a keyspace in the session, and use the method for the table creation without any parameter — in this case, the table will be created in the keyspace the session is currently using

3.4. Insert Data

3.4 插入数据

In addition, the driver provides prepared and bounded statements.

此外,司机还提供了有准备和有约束的报表。

The PreparedStatement is typically used for queries executed often, with changes only in the values.

PreparedStatement 通常用于经常执行的查询,仅在值上有变化。

We can fill the PreparedStatement with the values we need. After that, we’ll create a BoundStatement and execute it.

我们可以在PreparedStatement中填写我们需要的值。之后,我们将创建一个BoundStatement并执行它。

Let’s write a method for inserting some data into the database:

让我们写一个方法来向数据库插入一些数据。

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. Query Data

3.5.查询数据

Now, let’s add a method that creates a simple query to get the data we’ve stored in the database:

现在,让我们添加一个方法,创建一个简单的查询来获取我们存储在数据库中的数据。

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. Putting It All Together

3.6.归纳总结

Finally, let’s see an example using each section we’ve covered in this tutorial:

最后,让我们看看使用本教程中所涉及的每个部分的例子。

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();
    }
}

After we execute our example, as a result, we can see in the logs that the data was properly stored in the database:

在我们执行完我们的例子后,作为一个结果,我们可以在日志中看到,数据被正确地存储在数据库中。

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. Conclusion

4.总结

In this tutorial, we covered the basic concepts of the DataStax Java Driver for Apache Cassandra. We connected to the database and created a keyspace and table. Also, we inserted data into the table and ran a query to retrieve it.

在本教程中,我们介绍了DataStax Java Driver for Apache Cassandra的基本概念。我们连接到数据库并创建了一个键空间和表。同时,我们在表中插入了数据,并运行了一个查询来检索数据。

As always, the source code for this tutorial is available over on Github.

像往常一样,本教程的源代码可在Github上获得