ZonedDateTime with Spring Data MongoDB – 使用Spring Data MongoDB的ZonedDateTime

最后修改: 2018年 11月 10日

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

1. Overview

1.概述

Spring Data MongoDB module improves readability and usability when interacting with a MongoDB database in Spring projects.

Spring Data MongoDB模块改善了在Spring项目中与MongoDB数据库交互时的可读性和可用性。

In this tutorial, we’ll focus on how to handle the ZonedDateTime Java objects when reading and writing into a MongoDB database.

在本教程中,我们将重点介绍在向 MongoDB 数据库读写时如何处理 ZonedDateTime Java 对象。

2. Setup

2.设置

To work with Spring Data MongoDB module, we need to add the following dependency:

为了与Spring Data MongoDB模块一起工作,我们需要添加以下依赖关系。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>

The latest version of the library can be found here.

该库的最新版本可以在这里找到。

Let’s define a model class called Action (with a ZonedDateTime attribute):

让我们定义一个叫做Action的模型类(有一个ZonedDateTime属性)。

@Document
public class Action {
    @Id
    private String id;

    private String description;
    private ZonedDateTime time;
    
    // constructor, getters and setters 
}

To interact with the MongoDB, we’ll also create an interface that extends the MongoRepository:

为了与 MongoDB 进行交互,我们还将创建一个扩展了 MongoRepository 的接口。

public interface ActionRepository extends MongoRepository<Action, String> { }

Now we’ll define a test that will insert an Action object into a MongoDB and assert that it was stored with the correct time. In the assert evaluation, we’re removing the nanoseconds information since the MongoDB Date type has a precision of milliseconds:

现在我们将定义一个测试,该测试将把一个Action对象插入MongoDB,并断言它是以正确的时间存储的。在断言评估中,我们将删除纳秒信息,因为MongoDB的Date类型的精度为毫秒。

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

Out of the box, we will get the following error when running our test:

开箱后,我们在运行测试时将得到以下错误。

org.bson.codecs.configuration.CodecConfigurationException:
  Can't find a codec for class java.time.ZonedDateTime

Spring Data MongoDB has no ZonedDateTime converters defined. Let’s see how we can configure them.

Spring Data MongoDB没有定义ZonedDateTime转换器。让我们看看如何配置它们。

3. The MongoDB Converters

3.MongoDB转换器

We can handle ZonedDateTime objects (across all models) by defining a converter for reading from a MongoDB and one for writing into it.

我们可以通过定义一个用于从MongoDB读取的转换器和一个用于写入MongoDB的转换器来处理ZonedDateTime对象(跨越所有模型)。

For reading, we’re converting from a Date object into a ZonedDateTime object. In the next example, we use the ZoneOffset.UTC since Date object does not store zone information:

对于阅读,我们要从Date对象转换为ZonedDateTime对象。在下一个例子中,我们使用ZoneOffset.UTC,因为Date对象并不存储区域信息。

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

Then, we’re converting from a ZonedDateTime object into a Date object. We can add the zone information to another field if needed:

然后,我们要从一个ZonedDateTime对象转换为一个Date对象。如果需要,我们可以将区域信息添加到另一个字段。

public class ZonedDateTimeWriteConverter implements Converter<ZonedDateTime, Date> {
    @Override
    public Date convert(ZonedDateTime zonedDateTime) {
        return Date.from(zonedDateTime.toInstant());
    }
}

Since Date objects do not store a zone offset, we use UTC in our examples. With the ZonedDateTimeReadConverter and the ZonedDateTimeWriteConverter added to the MongoCustomConversions, our test will now pass.

由于Date对象不存储区域偏移,我们在示例中使用UTC。随着ZonedDateTimeReadConverterZonedDateTimeWriteConverter被添加到MongoCustomConversions,我们的测试现在将通过。

A simple printing of the stored object will look like this:

对存储对象的简单打印将看起来像这样。

Action{id='testId', description='click', time=2018-11-08T08:03:11.257Z}

To learn more about how to register MongoDB converters, we can refer to this tutorial.

要了解更多关于如何注册MongoDB转换器的信息,我们可以参考这个教程

4. Conclusions

4.结论

In this quick article, we saw how to create MongoDB converters in order to handle Java ZonedDateTime objects.

在这篇快速文章中,我们看到了如何创建MongoDB转换器,以便处理Java ZonedDateTime对象。

The implementation of all of these snippets can be found over on GitHub.

所有这些片段的实现都可以在GitHub上找到over