1. Обзор
DataStax Distribution Apache Cassandra — это готовая к работе распределенная база данных, совместимая с Cassandra с открытым исходным кодом. Он добавляет несколько функций, недоступных в дистрибутиве с открытым исходным кодом, включая мониторинг, улучшенную пакетную обработку и потоковую обработку данных.
DataStax также предоставляет клиент Java для своего дистрибутива Apache Cassandra. Этот драйвер легко настраивается и может использовать все дополнительные функции дистрибутива DataStax, но он также полностью совместим с версией с открытым исходным кодом.
В этом руководстве мы увидим, как использовать Java-драйвер DataStax для Apache Cassandra для подключения к базе данных Cassandra и выполнения основных операций с данными.
2. Зависимость от Maven
Чтобы использовать драйвер Java DataStax для Apache Cassandra, нам нужно включить его в наш путь к классам.
С 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. Создать ключевое пространство
Теперь, когда у нас есть подключение к базе данных, нам нужно создать наше пространство ключей. Начнем с написания простого класса репозитория для работы с нашим пространством ключей.
В этом руководстве мы будем использовать стратегию репликации SimpleStrategy
с числом реплик, равным 1 :
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. Создать таблицу
Драйвер предоставляет операторы для настройки и выполнения запросов в базе данных. Например, мы можем установить пространство ключей для использования индивидуально в каждом операторе .
Мы определим модель видео
и создадим таблицу для ее представления:
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
.
Идея перегрузки этого метода состоит в том, чтобы иметь два варианта создания таблицы:
- Создайте таблицу в определенном пространстве ключей, отправив имя пространства ключей в качестве параметра, независимо от того, какое пространство ключей использует текущий сеанс.
- Начните использовать пространство ключей в сеансе и используйте метод создания таблицы без каких-либо параметров — в этом случае таблица будет создана в пространстве ключей, которое сеанс использует в данный момент.
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.foreach.datastax.cassandra.Application - [id:733249eb-914c-4153-8698-4f58992c4ad4, title:Video Title 1, creationDate: 2019-07-10T19:43:35.112Z]
INFO com.foreach.datastax.cassandra.Application - [id:a6568236-77d7-42f2-a35a-b4c79afabccf, title:Video Title 2, creationDate: 2019-07-09T19:43:35.181Z]
4. Вывод
В этом руководстве мы рассмотрели основные концепции драйвера Java DataStax для Apache Cassandra. Мы подключились к базе данных и создали пространство ключей и таблицу. Кроме того, мы вставили данные в таблицу и выполнили запрос для их извлечения.
Как всегда, исходный код этого руководства доступен на Github .