ZonedDateTime с данными Spring MongoDB

ZonedDateTime с данными Spring MongoDB

1. обзор

МодульSpring Data MongoDB улучшает читаемость и удобство использования при взаимодействии с базой данных MongoDB в проектах Spring.

В этом руководстве мы сосредоточимся на том, как обрабатывать объекты JavaZonedDateTime при чтении и записи в базу данных MongoDB.

2. Настроить

Для работы с модулем Spring Data MongoDB нам нужно добавить следующую зависимость:


    org.springframework.data
    spring-data-mongodb
    2.1.2.RELEASE

Последнюю версию библиотеки можно найтиhere.

Давайте определим класс модели с именем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 в MongoDB и подтвердит, что он был сохранен с правильным временем. При оценке assert мы удаляем информацию о наносекундах, поскольку тип MongoDBDate имеет точность до миллисекунд:

@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 has no ZonedDateTime converters defined. Давайте посмотрим, как мы можем их настроить.

3. Конвертеры MongoDB

Мы можем обрабатывать объектыZonedDateTime (во всех моделях), определив конвертер для чтения из MongoDB и один для записи в него.

Для чтения мы конвертируем объектDate в объектZonedDateTime. В следующем примере мы используемZoneOffset.UTC, поскольку объектDate не хранит информацию о зоне:

public class ZonedDateTimeReadConverter implements Converter {
    @Override
    public ZonedDateTime convert(Date date) {
        return date.toInstant().atZone(ZoneOffset.UTC);
    }
}

Затем мы конвертируем объектZonedDateTime в объектDate. При необходимости мы можем добавить информацию о зоне в другое поле:

public class ZonedDateTimeWriteConverter implements Converter {
    @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, мы можем обратиться кthis tutorial.

4. Выводы

В этой быстрой статье мы увидели, как создать конвертеры MongoDB для обработки объектов JavaZonedDateTime.

Реализацию всех этих фрагментов можно найти вover on GitHub.