如何将java.time.Duration映射到具有类型时间的Cassandra DB列

时间:2018-06-04 14:57:40

标签: java cassandra codec duration

目标:

将java.time.Duration从JDK8 +映射到类型为time的Cassandra DB列。

情况:

我无法找到任何标准映射或任何编解码器(即使在具有额外编解码器的maven依赖项中)也能够做到这一点。 它是一个带有Cassandra DB数据存储驱动程序的java 8 maven项目。

问题:

有人知道这个或任何编解码器的可行解决方案吗?如果没有,是通过java.sql.time进行解决方法的最佳方式还是可能的?

如果我忘记了一些重要细节,请在下面评论。

1 个答案:

答案 0 :(得分:3)

TL;博士

使用Cassandra类型duration而不是time

使用java.time.Duration类传递或解析标准ISO 8601字符串。

Duration.parse( "PT1H30M" )  // Parse ISO 8601 string into a `Duration` object.
        .toString()          // Generate a ISO 8601 string from the `Duration` object.

Duration不是时间

java.time.Duration类表示未附加到时间轴的时间跨度。它代表一个时间。

Cassandra time类型定义为:

  

值被编码为64位有符号整数,表示自午夜以来的纳秒数。值可以表示为字符串,例如13:30:54.234。

因此,您不应使用Cassandra Duration类型存储time值。

您还有其他选择。

一种选择是存储标准ISO 8601 textual representation of a durationPnYnMnDTnHnMnS。示例:一个半小时为PT1H30M。这个选项更加真实,但是这些值无法在Cassandra中进行比较或排序,因为它们只是按时间顺序排列的没有字母排序的文本。另请参阅本答案中下面的“Cassandra持续时间”部分。

另一个选项是提取Duration内部使用的两个数字:

  • 64位整数,整秒计数。
  • 32位整数,小数秒内的纳秒数。

如果你坚持,你可以使用这些数字生成一个值来存储为Cassandra time,但是你违反了语义。

long fakeNanosSinceMidnight = TimeUnit.SECONDS.toNanos( duration.getSeconds ) + duration.getNano() ;  // NOT recommended, but if you insist on abusing Cassandra semantics, here you go. 

Cassandra Duration

Cassandra documentation says内置duration类型。我不是Cassandra的用户所以我不能保证它。

doc说它接受标准的ISO 8601持续时间字符串作为输入。 Java中的Duration::toString方法生成此类字符串,而Duration::parse解析相同的字符串。

String inputDurationForCassandra = duration.toString() ;

解析。

Duration duration = Duration.parse( myCassandraDurationString ) ;

请注意,Java使用Duration类几天(通用的24小时块,而不是日历天),小时,分钟和秒。 Period类代表年,月,日。结合这两个概念通常没有意义。但是如果你坚持,你可以使用PeriodDuration项目库中的ThreeTen-Extra类。