1. Обзор
Модуль Spring Data MongoDB улучшает читаемость и удобство использования при взаимодействии с базой данных MongoDB в проектах Spring.
В этом руководстве мы сосредоточимся на том, как обрабатывать объекты Java ZonedDateTime
при чтении и записи в базу данных MongoDB.
2. Настройка
Для работы с модулем Spring Data MongoDB нам нужно добавить следующую зависимость:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
Последнюю версию библиотеки можно найти здесь .
Давайте определим класс модели под названием Action
(с атрибутом ZonedDateTime
):
@Document
public class Action {
@Id
private String id;
private String description;
private ZonedDateTime time;
// constructor, getters and setters
}
Для взаимодействия с MongoDB мы также создадим интерфейс, расширяющий MongoRepository
:
public interface ActionRepository extends MongoRepository<Action, String> { }
Теперь мы определим тест, который вставит объект Action
в MongoDB и подтвердит, что он был сохранен с правильным временем. В оценке утверждения мы удаляем информацию о наносекундах, поскольку тип даты
MongoDB имеет точность в миллисекундах:
@Test
public void givenSavedAction_TimeIsRetrievedCorrectly() {
String id = "testId";
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
actionRepository.save(new Action(id, "click-action", now));
Action savedAction = actionRepository.findById(id).get();
Assert.assertEquals(now.withNano(0), savedAction.getTime().withNano(0));
}
Из коробки мы получим следующую ошибку при запуске нашего теста:
org.bson.codecs.configuration.CodecConfigurationException:
Can't find a codec for class java.time.ZonedDateTime
Spring Data MongoDB не имеет определенных преобразователей ZonedDateTime .
Давайте посмотрим, как мы можем их настроить.
3. Преобразователи MongoDB
Мы можем обрабатывать объекты ZonedDateTime
(во всех моделях), определяя преобразователь для чтения из MongoDB и один для записи в нее.
Для чтения мы конвертируем объект Date
в объект ZonedDateTime
. В следующем примере мы используем ZoneOffset.UTC,
поскольку объект Date
не хранит информацию о зоне:
public class ZonedDateTimeReadConverter implements Converter<Date, ZonedDateTime> {
@Override
public ZonedDateTime convert(Date date) {
return date.toInstant().atZone(ZoneOffset.UTC);
}
}
Затем мы преобразуем объект ZonedDateTime
в объект Date
. При необходимости мы можем добавить информацию о зоне в другое поле:
public class ZonedDateTimeWriteConverter implements Converter<ZonedDateTime, Date> {
@Override
public Date convert(ZonedDateTime zonedDateTime) {
return Date.from(zonedDateTime.toInstant());
}
}
Поскольку объекты Date
не хранят смещение зоны, в наших примерах мы используем UTC .
Теперь, когда ZonedDateTimeReadConverter
и ZonedDateTimeWriteConverter
добавлены в MongoCustomConversions
, наш тест будет пройден.
Простая печать сохраненного объекта будет выглядеть так:
Action{id='testId', description='click', time=2018-11-08T08:03:11.257Z}
Чтобы узнать больше о том, как зарегистрировать преобразователи MongoDB, мы можем обратиться к этому руководству .
4. Выводы
В этой быстрой статье мы увидели, как создавать преобразователи MongoDB для обработки объектов Java ZonedDateTime
.
Реализацию всех этих фрагментов можно найти на GitHub .