在 DynamoDB 中处理 Java8 日期和时间的最佳方法
Best approach to handle Java8 date and time in DynamoDB
我研究了使用 Java SDK 存储日期和时间的 DynamoDB 选项。据我所知,Java8 LocalDate 和 LocalDateTime 需要自定义转换器,而对于旧日期、日历和 Joda 时间 LocalDateTime,有一些注释。
根据文档,@DynamoDBTypeConvertedTimestamp 支持标准日期类型转换,例如 java.util.Calendar、Long。 @DynamoDBTypeConvertedEpochDate 可用于将日期、日历和 org.joda.time.DateTime 转换为数值。
同时,如果我不在 Date 字段上放置任何注释,它会被保存,就像上面有 @DynamoDBTypeConvertedTimestamp 一样,甚至范围查询也能成功。
是否有人知道解释不同的可能方法,并就从 DynamoDB 存储和检索 Java 日期和时间对象的最佳方法发表意见?
TLDR;这取决于日期、时间等将如何使用。
长答案
这将取决于您的用例,因此没有硬性的 "best" 方法。但是,需要牢记一些注意事项。
您的 table 架构中使用的值如何?
如果 Java 8 date/time 将用作排序键,请考虑使用自定义转换器将其转换为字符串。如果这样做,则可以在查询的关键条件表达式中使用 begins_with
运算符,例如 begins_with(myDate, "2018-12")
。如果您想搜索特定年、月、日、小时等的所有内容,能够像这样查询将使您的代码简单得多
如果您将该值用作 DynamoDB TTL 属性,则必须将其转换为数字时间戳。这是使用 TTL 功能的要求。
我们在谈论 java.time
类 中的哪一个?
Some of the classes in the java.time
package 没有自然的数字转换。例如,LocalDate
充其量也很难转换为数字。 LocalDate 2018-12-10
转换为 20181210
最有意义,但在这一点上,您必须编写足够多的代码,您也可以只使用内置的 LocalDate.toString()
和 LocalDate.parse()
.
您需要多久查看一次数据库以查找错误或修复错误数据?
如果您经常在数据库中乱搞(希望不是这种情况),请使用人类可读的内容。当他们在半夜被呼叫时,没有人愿意弄清楚 2018-12-05T17:23:19.483+08:30
是在 1544572463
之前还是之后。
您的应用程序对增加的延迟有多敏感?
我没有观察到 DynamoDB 在将日期存储为字符串与数字方面有任何可衡量的性能差异。但是,string parsing is slower that using a number 会创建一个 java.time
对象,因此如果将日期存储为字符串,可能会对您的应用程序产生轻微影响。
别让自定义转换器吓跑了你
为 java.time
api 编写它们真的很容易。以下是如何实现 LocalDateTime
的转换器,将其转换为 String
.
public class LocalDateTimeToStringTypeConverter implements DynamoDBTypeConverter<String, LocalDateTime> {
@Override
public String convert(LocalDateTime localDateTime) {
return localDateTime.toString();
}
@Override
public LocalDateTime unconvert(String s) {
return LocalDateTime.parse(s);
}
}
尝试使用@DynamoDBTyped 注释日期字段,这是一个覆盖 dynamoDB 中标准属性类型绑定的注释。所以它会将日期转换为 Attribute Type = S ,这在 DynamoDM 中是 String 。希望对你有帮助
@DynamoDBTyped(DynamoDBAttributeType.S)
private LocalDate startDate;
我研究了使用 Java SDK 存储日期和时间的 DynamoDB 选项。据我所知,Java8 LocalDate 和 LocalDateTime 需要自定义转换器,而对于旧日期、日历和 Joda 时间 LocalDateTime,有一些注释。
根据文档,@DynamoDBTypeConvertedTimestamp 支持标准日期类型转换,例如 java.util.Calendar、Long。 @DynamoDBTypeConvertedEpochDate 可用于将日期、日历和 org.joda.time.DateTime 转换为数值。
同时,如果我不在 Date 字段上放置任何注释,它会被保存,就像上面有 @DynamoDBTypeConvertedTimestamp 一样,甚至范围查询也能成功。
是否有人知道解释不同的可能方法,并就从 DynamoDB 存储和检索 Java 日期和时间对象的最佳方法发表意见?
TLDR;这取决于日期、时间等将如何使用。
长答案
这将取决于您的用例,因此没有硬性的 "best" 方法。但是,需要牢记一些注意事项。
您的 table 架构中使用的值如何?
如果 Java 8 date/time 将用作排序键,请考虑使用自定义转换器将其转换为字符串。如果这样做,则可以在查询的关键条件表达式中使用 begins_with
运算符,例如 begins_with(myDate, "2018-12")
。如果您想搜索特定年、月、日、小时等的所有内容,能够像这样查询将使您的代码简单得多
如果您将该值用作 DynamoDB TTL 属性,则必须将其转换为数字时间戳。这是使用 TTL 功能的要求。
我们在谈论 java.time
类 中的哪一个?
Some of the classes in the java.time
package 没有自然的数字转换。例如,LocalDate
充其量也很难转换为数字。 LocalDate 2018-12-10
转换为 20181210
最有意义,但在这一点上,您必须编写足够多的代码,您也可以只使用内置的 LocalDate.toString()
和 LocalDate.parse()
.
您需要多久查看一次数据库以查找错误或修复错误数据?
如果您经常在数据库中乱搞(希望不是这种情况),请使用人类可读的内容。当他们在半夜被呼叫时,没有人愿意弄清楚 2018-12-05T17:23:19.483+08:30
是在 1544572463
之前还是之后。
您的应用程序对增加的延迟有多敏感?
我没有观察到 DynamoDB 在将日期存储为字符串与数字方面有任何可衡量的性能差异。但是,string parsing is slower that using a number 会创建一个 java.time
对象,因此如果将日期存储为字符串,可能会对您的应用程序产生轻微影响。
别让自定义转换器吓跑了你
为 java.time
api 编写它们真的很容易。以下是如何实现 LocalDateTime
的转换器,将其转换为 String
.
public class LocalDateTimeToStringTypeConverter implements DynamoDBTypeConverter<String, LocalDateTime> {
@Override
public String convert(LocalDateTime localDateTime) {
return localDateTime.toString();
}
@Override
public LocalDateTime unconvert(String s) {
return LocalDateTime.parse(s);
}
}
尝试使用@DynamoDBTyped 注释日期字段,这是一个覆盖 dynamoDB 中标准属性类型绑定的注释。所以它会将日期转换为 Attribute Type = S ,这在 DynamoDM 中是 String 。希望对你有帮助
@DynamoDBTyped(DynamoDBAttributeType.S)
private LocalDate startDate;