ZonedDateTime 与 Spring Data MongoDB

1. 概述

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

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

2. 设置

要使用 Spring Data MongoDB 模块,我们需要添加以下依赖项:

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

可以在[此处](https://search.maven.org/classic/#search|ga|1|g%3A"org.springframework.data" AND a%3A"spring-data-mongodb")找到该库的最新版本。

让我们定义一个名为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 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)); 
}

开箱即用,我们在运行测试时会收到以下错误:

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

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

3. MongoDB 转换器

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

为了便于阅读,我们将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());
    }
}

创建自己的MongoConfig:

@EnableMongoRepositories(basePackages = { "com.baeldung" })
public class MongoConfig extends AbstractMongoClientConfiguration {

    private final List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();

    @Override
    protected String getDatabaseName() {
        return "test";
    }

    @Override
    public MongoCustomConversions customConversions() {
        converters.add(new ZonedDateTimeReadConverter());
        converters.add(new ZonedDateTimeWriteConverter());
        return new MongoCustomConversions(converters);
    }

}

使用@EnableMongoRepositories注解来指定开启MongoDB存储库。类似于JPA中的@EnableJpaRepositories

由于Date对象不存储时区偏移量,因此我们在示例中使用 UTC。将 ZonedDateTimeReadConverterZonedDateTimeWriteConverter添加到 MongoCustomConversions 后,我们的测试现在将通过。

存储对象的简单打印如下所示:

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

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

4. 结论

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱游泳的老白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值