1. Обзор
Apache Cassandra — это масштабируемая база данных NoSQL. Он обеспечивает постоянную доступность без единой точки отказа . Кроме того, Cassandra способна обрабатывать большие объемы данных с исключительной производительностью.
В этом руководстве мы рассмотрим подключение к Cassandra с использованием Spring Data и Docker. Кроме того, мы будем использовать абстракцию репозитория Spring Data для работы со слоем данных Cassandra.
Мы увидим, как сохранить различные значения даты Java в Cassandra. Наконец, мы исследуем, как эти значения даты сопоставляются с типами Cassandra.
2. Весенние данные для Кассандры
Spring Data for Apache Cassandra предлагает разработчикам Spring знакомый интерфейс для работы с Cassandra . Этот проект применяет основные концепции Spring к разработке решений с использованием хранилища данных Cassandra.
Spring Data позволяет нам создавать репозитории на основе распространенных интерфейсов Spring. Это также позволяет использовать QueryBuilders
, чтобы исключить необходимость изучения языка запросов Cassandra (CQL). Проект предоставляет простые аннотации, которые позволяют использовать расширенное сопоставление объектов.
Есть два важных вспомогательных класса:
CqlTemplate
обрабатывает общие операции доступа к данным .CassandraTemplate
обеспечивает сопоставление объектов
Проект имеет заметное сходство с основной поддержкой JDBC в Spring.
3. Настройка тестовой среды
Чтобы начать работу, нам нужно настроить подключение к экземпляру Cassandra.
Обратите внимание, что вместо этого мы также можем подключиться к базе данных Astra DB, которая представляет собой облачную базу данных, построенную на Apache Cassandra.
В этом руководстве показано, как подключиться к базе данных Datastax Astra DB .
3.1. Кассандра Контейнер
Настроим и запустим Cassandra с помощью библиотеки Testcontainers
. Для начала мы определим контейнер Cassandra и предоставим ему доступ к определенному порту:
@Container
public static final CassandraContainer cassandra = (CassandraContainer) new CassandraContainer("cassandra:3.11.2")
.withExposedPorts(9042);
Затем нам нужно переопределить свойства теста, необходимые для Spring Data, чтобы иметь возможность установить соединение с контейнером Cassandra:
TestPropertyValues.of(
"spring.data.cassandra.keyspace-name=" + KEYSPACE_NAME,
"spring.data.cassandra.contact-points=" + cassandra.getContainerIpAddress(),
"spring.data.cassandra.port=" + cassandra.getMappedPort(9042)
).applyTo(configurableApplicationContext.getEnvironment());
Наконец, перед созданием каких-либо объектов/таблиц нам нужно создать пространство ключей:
session.execute("CREATE KEYSPACE IF NOT EXISTS " + KEYSPACE_NAME + " WITH replication = {'class':'SimpleStrategy','replication_factor':'1'};");
Пространство ключей — это просто контейнер данных в Cassandra. По сути, это очень похоже на базу данных в СУБД.
3.2. Репозиторий Кассандры
Поддержка репозитория Spring Data значительно упрощает реализацию DAO . Начнем с создания простого DAO.
Аннотация @Table
, представленная в пакете org.springframework.data.cassandra.core.mapping
, позволяет отображать объекты домена:
@Table
public class Person {
@PrimaryKey
private UUID id;
private String firstName;
private String lastName;
public Person(UUID id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
//getters, setters, equals and hash code
}
Далее мы определим репозиторий Spring Data для нашего DAO, расширив интерфейс CassandraRepository :
@Repository
public interface PersonRepository extends CassandraRepository<Person, UUID> {}
Наконец, нам нужно определить два дополнительных свойства, прежде чем мы сможем начать писать интеграционные тесты:
spring.data.cassandra.schema-action=create_if_not_exists
spring.data.cassandra.local-datacenter=datacenter1
Первое свойство гарантирует, что Spring Data автоматически создаст для нас аннотированные таблицы.
Следует отметить, что этот параметр не рекомендуется для производственных систем .
4. Использование значений даты
В современных версиях Spring Data для Apache Cassandra работа со значениями даты довольно проста. Spring Data автоматически обеспечит правильное сопоставление типов дат Java с представлением Apache Cassandra и из него.
4.1. Тип локальной даты
Давайте добавим в наш Person
DAO новое поле BirthdayDate
типа LocalDate :
``
@Test
public void givenValidPersonUsingLocalDate_whenSavingIt_thenDataIsPersisted() {
UUID personId = UUIDs.timeBased();
Person newPerson = new Person(personId, "Luka", "Modric");
newPerson.setBirthDate(LocalDate.of(1985, 9, 9));
personRepository.save(newPerson);
List<Person> savedPersons = personRepository.findAllById(List.of(personId));
assertThat(savedPersons.get(0)).isEqualTo(newPerson);
}
Spring Data автоматически преобразует LocalDate
Java в тип даты
Cassandra . Значение LocalDate
в DAO идентично после сохранения и извлечения записи из Cassandra.
4.2. Тип LocalDateTime
Давайте добавим еще одно поле с именем lastVisitedDate
типа LocalDateTime
в наш DAO Person :
@Test
public void givenValidPersonUsingLocalDateTime_whenSavingIt_thenDataIsPersisted() {
UUID personId = UUIDs.timeBased();
Person newPerson = new Person(personId, "Luka", "Modric");
newPerson.setLastVisitedDate(LocalDateTime.of(2021, 7, 13, 11, 30));
personRepository.save(newPerson);
List<Person> savedPersons = personRepository.findAllById(List.of(personId));
assertThat(savedPersons.get(0)).isEqualTo(newPerson);
}
Spring Data автоматически преобразует LocalDateTime
Java в тип временной метки
Cassandra . Значение LocalDateTime
в DAO идентично после сохранения и извлечения записи из Cassandra.
4.3. Устаревший тип даты
Наконец, давайте добавим поле lastPurchasedDate
устаревшего типа Date
в наш DAO Person :
@Test
public void givenValidPersonUsingLegacyDate_whenSavingIt_thenDataIsPersisted() {
UUID personId = UUIDs.timeBased();
Person newPerson = new Person(personId, "Luka", "Modric");
newPerson.setLastPurchasedDate(new Date(LocalDate.of(2021, 7, 13).toEpochDay()));
personRepository.save(newPerson);
List<Person> savedPersons = personRepository.findAllById(List.of(personId));
assertThat(savedPersons.get(0)).isEqualTo(newPerson);
}
Как и в случае с LocalDateTime,
Spring Data преобразует тип Java java.util.Date
в тип метки времени
Cassandra .
4.4. Сопоставленные типы Cassandra
Давайте проверим данные, которые были сохранены в Cassandra, с помощью CQLSH. Это оболочка командной строки для взаимодействия с Cassandra через CQL.
Чтобы проверить, какие данные были сохранены в контейнере Cassandra во время выполнения теста, мы можем просто поставить точку останова в нашем тесте. Во время приостановленного выполнения теста мы можем затем подключиться к CLI контейнера Docker через приложение Docker Desktop:
После подключения к CLI контейнера Docker мы должны сначала выбрать пространство ключей, а затем таблицу:
# cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.2 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> USE test;
cqlsh:test> select * from person;
В результате CQLSH выведет нам форматированный вывод данных, сохраненных в таблице:
id | birthdate | firstname | lastname | lastpurchaseddate | lastvisiteddate
--------------------------------------+------------+-----------+----------+-------------------+-----------------
9abef910-e3fd-11eb-9829-c5149ac796de | 1985-09-09 | Luka | Modric | null | null
Однако мы также хотели бы проверить типы данных, используемые для определенных столбцов даты:
cqlsh:test> DESC TABLE person;
Выходные данные возвращают команду CQL, используемую для создания таблицы. Поэтому он содержит определения всех типов данных:
CREATE TABLE test.person (
id uuid PRIMARY KEY,
birthdate date,
firstname text,
lastname text,
lastpurchaseddate timestamp,
lastvisiteddate timestamp
)
5. Вывод
В этой статье мы рассмотрели работу с различными значениями дат в Spring Data для Apache Cassandra.
В примерах мы рассмотрели работу с LocalDate
, LocalDateTime
и устаревшим типом Date
Java. Мы увидели, как подключение к экземпляру Cassandra началось с помощью Testcontainers
. Наконец, мы использовали абстракцию репозитория Spring Data для управления данными, хранящимися в Cassandra.
Как всегда, исходный код доступен на GitHub .