• ZonedDateTime 与 Spring Data MongoDB


    1. 概述

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

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

    2. 设置

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

    <dependency>
        <groupId>org.springframework.datagroupId>
        <artifactId>spring-data-mongodbartifactId>
        <version>3.0.3.RELEASEversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可以在[此处](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 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

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

    现在我们将定义一个测试,将一个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)); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

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

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    public class ZonedDateTimeWriteConverter implements Converter<ZonedDateTime, Date> {
        @Override
        public Date convert(ZonedDateTime zonedDateTime) {
            return Date.from(zonedDateTime.toInstant());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    创建自己的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);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

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

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

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

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

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

    4. 结论

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

  • 相关阅读:
    动态规划 | 不同路径、整数拆分、不同的二叉搜索树 | leecode刷题笔记
    90. 子集 II
    多线程进阶:常见数据结构的安全性分析
    进程之间是怎么协作的(软件实现方法)
    第三章:Spring常用注解解释
    【华为云】E: You don‘t have enough free space in /var/cache/apt/archives/.
    [yolo系列:yolov7添加可变形卷积Deformable Conv V2]
    POI和EasyExcel
    反射、枚举、lambda——小记
    电子科学与技术毕设题目选题推荐
  • 原文地址:https://blog.csdn.net/wjw465150/article/details/127916059