MySQL DATETIME 精度(joda-time、Hibernate、org.jadira.usertype、hbm2ddl)
Posted
技术标签:
【中文标题】MySQL DATETIME 精度(joda-time、Hibernate、org.jadira.usertype、hbm2ddl)【英文标题】:MySQL DATETIME precision (joda-time, Hibernate, org.jadira.usertype, hbm2ddl) 【发布时间】:2014-05-12 04:21:45 【问题描述】:在我的 hibernate-4 实体中,我正在使用推荐的 jadira usertypes 映射一个 joda-time DateTime 属性:
@Entity
@Table(name="timing")
public class TimingEntity
...
@Basic(optional=false)
@Column(name="moment")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getMoment()
...
我的数据库是 mysql。将休眠属性hbm2ddl.auto
设置为create
值,我在timing
表中生成了以下列:
CREATE TABLE `timing` (
...
`moment` DATETIME NOT NULL,
...
)
生成的CREATE TABLE
包含 DATETIME 列。 MySQL 中的 DATETIME 只有秒精度,没有小数部分。为了启用小数部分,最多为微秒,MySQL 5.6.4 和更高版本的enablesDATETIME(precision)
列,例如DATETIME(3)
具有毫秒精度。
我的问题是——有没有办法为我用 hbm2ddl 生成的时间字段指定精度?至少,这是 jadira 用户类型、java.sql 还是 jdbc 驱动程序机制的问题?
PS 当我手动修改数据库表以获得我想要的精确列精度时,例如 DATETIME(3)
,一切正常 - joda DateTimes 以毫秒精度从数据库中写入和读取。
【问题讨论】:
【参考方案1】:我发现了另一种解决方案,它不允许在 @Column
注释中对 MySQL 列定义 sn-p 进行硬编码。通过覆盖org.hibernate.dialect.MySQLDialect
来定义你自己的hibernate方言:
package org.yourproject;
import java.sql.Types;
import org.hibernate.dialect.MySQL5Dialect;
public class MySQL564PlusDialect extends MySQL5Dialect
public MySQL564PlusDialect()
super();
registerColumnType( Types.TIMESTAMP, 6, "datetime($l)" );
并将其指定为休眠属性hibernate.dialect=org.yourproject.MySQL564PlusDialect
(您要扩展的方言可能会有所不同,例如改为org.hibernate.dialect.MySQL5InnoDBDialect
)。
现在您可以使用length
属性在@Column
注释中调整DATETIME
的精度:
@Basic(optional=false)
@Column(name="moment", length=3)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getMoment()
...
这将产生DATETIME(3)
列定义,意思是毫秒精度。如果您需要简单的DATETIME
(没有小数秒),请不要指定长度。您可以使用高达 6 的 length
值,这意味着微秒精度。
如果您碰巧使用了与上述不同的方言(例如标准org.hibernate.dialect.MySQLDialect
或其他数据库),这不会破坏您的代码:@Column
上的length
属性将被忽略。
附:使用@Column
的precision
属性而不是length
会更明智,但是在我自己的方言实现中用"datetime($p)"
简单地替换"datetime($l)"
模式并不适用。
【讨论】:
【参考方案2】:使用可以为它使用@Column#columnDefinition属性
@Basic(optional=false)
@Column(name="moment" columnDefinition="DATETIME(3) NOT NULL")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getMoment()
...
您也可以尝试@Column#precision 属性,但在文档中写道,这仅适用于小数。
【讨论】:
成功了,谢谢!columnDefinition
有效,precision
无效。然而,缺点是我开始在我的代码中依赖 mysql。以上是关于MySQL DATETIME 精度(joda-time、Hibernate、org.jadira.usertype、hbm2ddl)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中使用 DateTime.Now.Ticks 保持精度
SQL Server Compact 4.0 DateTime 精度不包括秒