如何在MySQL数据库中存储Java Instant
使用Java Date
对象,最简单的方法是将它们存储为MySql DateTime
对象(以UTC格式)。 切换到Instant
这种方法将不再起作用,因为MySQL DateTime
不提供存储纳秒的精度。 只是截断它们可能会导致新创建的Instant
对象与从数据库中读取的对象之间出现意外的比较结果。
BigDecimal
时间戳不会让我觉得它是一个优雅的解决方案:在MySql Workbench中编写select查询会变得更加困难,因为你必须在任何地方转换时间戳以使其可读,并且Java中的处理与Instant
或甚至Long
相比有点笨拙值。
什么是最好的方式去这里? 可能不是varchar
,对吗?
截断到微秒
显然,我们无法将Instant
的纳秒分辨率压缩到MySQL数据类型DateTime
和Timestamp
的微秒分辨率。
我想构建JDBC驱动程序是为了在接收Instant
时忽略纳秒,将值截断为微秒。 我建议您尝试一个实验来查看,并且可能会检查符合JDBC 4.2及更高版本的驱动程序的源代码。
Instant instant = Instant.now().with( ChronoField.NANO_OF_SECOND , 123_456_789L ) ; //Set the fractional second to a spefic number of nanoseconds. myPreparedStatement.setObject( … , instant ) ;
…和…
Instant instant2 = myResultSet.getObject( … , Instant.class ) ;
然后比较。
Boolean result = instant.equals( instant2 ) ; System.out.println( "instant: " + instant + " equals instant2: = " + instant2 + " is: " + result ) ;
您明智地担心从数据库中提取的值与原始值不匹配。 如果您的业务问题可以接受,一种解决方案是在原始数据中截断任何纳秒到微秒。 我一般推荐这种方法。
Instant instant = Instant().now().truncatedTo( ChronoUnit.MICROSECONDS ) ;
目前这种方法应该足够了,因为您的数据不太可能有纳秒。 据我所知,今天的主流计算机不具备能够捕获纳秒的硬件时钟。
从时代算起
如果您不能丢失任何可能存在的纳秒数据,请使用从纪元开始的计数。
我通常建议不要将日期时间作为纪元参考日期的计数。 但是,在将基于纳秒的值存储在MySQL和Postgres等数据库中的基于微秒的值中,您几乎没有其他选择。
存储一对整数
我建议遵循Instant
类的内部方法:使用一对数字,而不是使用自1970-01-01T00:00Z之类的纪元以来的极大数量的纳秒。
在数据库中将整数秒存储为整数。 在第二列存储中,以整数表示小数秒内的纳秒数。
您可以轻松地从/向Instant
对象提取/注入这些数字。 只涉及简单的64位long
数字; 不需要BigDecimal
或BigInteger
。 我想你可能能够为这两个数字中的至少一个使用32位整数列。 但为了简单起见,我会选择64位整数列类型,并与java.time.Instant
类的long对直接兼容。
long seconds = instant.getEpochSecond() ; long nanos = instant.getNano() ;
…和…
Instant instant = Instant.ofEpochSecond( seconds , nanos ) ;
按时间顺序排序时,您需要进行多级排序,首先在整个秒列上排序,然后在纳秒级秒列上进行排序。
- 如何将java.sql.Date转换为dd / MM / yyyy格式的java.util.Date?
- String – > java.util.Date – > java.sql.Date(带时间戳)
- 如何创建单个表达式,显示两个日期之间的时差,如年,月,日,小时,分钟,秒
- Java String to Date对象格式为“yyyy-mm-dd HH:mm:ss”
- 错过了在Java 8中修复JDBC日期处理的机会?
- 解析2位数年份:使用未知日期模式设置数据透视日期
- 在Joda-Time中,将DateTime设置为月初
- ToStringBuilder.reflectionToString(Object)以什么格式显示日期?
- SimpleDateFormat解析日期在某些Android设备上有所不同