简体   繁体   English

MySQL DATETIME精度(joda-time,Hibernate,org.jadira.usertype,hbm2ddl)

[英]MySQL DATETIME precision (joda-time, Hibernate, org.jadira.usertype, hbm2ddl)

In my hibernate-4 entity, I am mapping a joda-time DateTime property using the recommended jadira usertypes : 在我的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() {
       ...

My database is MySQL. 我的数据库是MySQL。 With hibernate property hbm2ddl.auto set to create value, I have the following column generated in my timing table: 将hibernate属性hbm2ddl.auto设置为create值,我在我的timing表中生成了以下列:

CREATE TABLE `timing` (
    ...
   `moment` DATETIME NOT NULL,
    ...
)

The generated CREATE TABLE contains the DATETIME column. 生成的CREATE TABLE包含DATETIME列。 The DATETIME in MySQL has only seconds precision, without fractional part. MySQL中的DATETIME只有秒精度,没有小数部分。 In order to enable fractional part, up to microseconds, MySQL 5.6.4 and higher enables DATETIME(precision) columns, for example DATETIME(3) to have milliseconds precision. 为了启用小数部分,高达微秒,MySQL 5.6.4及更高版本启用 DATETIME(precision)列,例如DATETIME(3)具有毫秒精度。

My question is -- is there way to specify precision for my temporal fields generated with hbm2ddl? 我的问题是 - 有没有办法为hbm2ddl生成的时间字段指定精度? At least, is this a matter of jadira usertypes, or java.sql, or jdbc driver machinery? 至少,这是jadira usertypes,或java.sql,或jdbc驱动程序机制的问题?

PS When I manually modify the DB table to have the exact column precision I want, say, DATETIME(3) , everything works OK - joda DateTimes are written and read from the DB with milliseconds precision. PS当我手动修改数据库表以获得我想要的精确列精度时,比如DATETIME(3) ,一切正常 - joda DateTimes以毫秒精度从DB写入和读取。

I've found one more solution that allows not to hardcode MySQL column definition snippet in your @Column annotation. 我找到了另一个解决方案,允许不在@Column注释中硬编码MySQL列定义片段。 Define your own hibernate dialect by overriding org.hibernate.dialect.MySQLDialect : 通过重写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)" );
   }
}

and specify it as hibernate property hibernate.dialect=org.yourproject.MySQL564PlusDialect (the dialect you'll want to extend may vary, eg org.hibernate.dialect.MySQL5InnoDBDialect instead). 并将其指定为hibernate属性hibernate.dialect=org.yourproject.MySQL564PlusDialect (您要扩展的方言可能会有所不同,例如org.hibernate.dialect.MySQL5InnoDBDialect )。

Now you can adjust precision of your DATETIME from within @Column annotation by using length attribute: 现在,您可以使用length属性从@Column注释中调整DATETIME精度:

@Basic(optional=false)
@Column(name="moment", length=3)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getMoment() {
 ...

which will produce DATETIME(3) column definition meaning milliseconds precision. 这将产生DATETIME(3)列定义,意味着毫秒精度。 If you need the simple DATETIME (no fractional seconds), just don't specify length. 如果您需要简单的DATETIME (无小数秒),则不要指定长度。 You can use value of length up to 6 which would mean microseconds precision. 您可以使用length最大为6的值,这意味着微秒的精度。

If you happen to use a dialect different from the above one (for example the standard org.hibernate.dialect.MySQLDialect or maybe some other database), that will not break your code: the length attribute on @Column will be ignored. 如果您碰巧使用与上述方言不同的方言(例如标准的org.hibernate.dialect.MySQLDialect或其他一些数据库),那么不会破坏您的代码: @Column上的length属性将被忽略。

PS It would be more sensible to exploit the precision attribute of @Column instead of length , but simple replacing of "datetime($l)" pattern with "datetime($p)" one in my own dialect implementation does not work offhand. PS这将是更明智的利用这个precision的属性@Column而不是length ,而是简单更换的"datetime($l)"与模式"datetime($p)"一个在我自己的方言实施不起作用的副手。

Use can use @Column#columnDefinition property for it 使用可以使用@ Column#columnDefinition属性

@Basic(optional=false)
@Column(name="moment" columnDefinition="DATETIME(3) NOT NULL")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getMoment() 
{   
   ...

Also you can try @Column#precision property, but in documentation is written that this working only for decimals. 您也可以尝试@ Column#precision属性,但在文档中写道,这只适用于小数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM