使用Hibernate进行Spring Boot:自动生成具有可保留几分之一秒时间的列的数据库架构

时间:2019-07-11 08:22:47

标签: mysql hibernate spring-boot jpa

我有一个spring-boot项目,在该项目中,我需要以毫秒为单位保存实体的最后修改时间-实际上,这是一个保留实体版本的审核属性。在我的开发环境中,我使用MySQL数据库,而MySQL的时间类型最多支持6位小数。因此,当手动创建架构时,我可以使用timestamp(6)datetime(6)定义相应的列。

但是我希望使用spring.jpa.hibernate.ddl-auto=update属性自动生成模式。我知道在生产环境中这不是一个好习惯,但是这个项目将成为许多其他项目的模板或种子。因此,我需要将其保留为通用形式,以使其不依赖于下划线数据库系统。

对于MySQL,我可以使用columnDefinition注解的@Column参数使其工作,如下所示。

@Version
@Column(columnDefinition= "datetime(6)")
Timestamp version;

但这不适用于datetime(6)不是有效的时间类型的其他数据库。

我尝试自动生成特定的数据库模式设置scale@Column(scale= 6))参数,但是它忽略了小数部分生成类型为datetime的列,而不是{{1} }。

我很好奇是否有办法做到这一点,尽管我不知道。

你们能给我一些建议吗?

更新

@crizzis在他的评论中告诉我,这是使用正确的 hibernate.dialect 的问题。因此,使用 org.hibernate.dialect.MySQL57Dialect ,我能够自动生成 datetime(6)列。然后,我尝试使用datetime(6)参数来控制小数部分的位数,但没有成功,它总是有6位数。

现在,我想知道如果不使用scale批注内的columnDefinition自变量是否可行。

1 个答案:

答案 0 :(得分:1)

MySql57Dialect(和/或MySql57InnoDbDialect,取决于Hibernate的版本),TIMESTAMP SQL类型已经映射到TIMESTAMP(6)数据库列类型:

registerColumnType( Types.TIMESTAMP, "datetime(6)" );

这意味着默认的列定义应支持微秒精度。最好的做法是让Hibernate生成架构而不覆盖列定义。对于大多数其他数据库,它将正常降级为简单的TIMESTAMP

如果将来想切换到也支持微秒精度的另一个数据库,请查找相关的Dialect;它可能会包含对该功能的支持,否则,您可以随时对其进行自定义。

  

然后我尝试用scale参数控制小数部分的位数,但没有成功,它总是有6位数。

这是因为在上面的registerColumnType调用中,TIMESTAMP的精度固定为6。如果要对其进行自定义,请铺开自己的自定义方言(从{ {1}})并使用以下命令覆盖定义:

MySql57Dialect

然后,您将可以使用registerColumnType(Types.TIMESTAMP, 6, "timestamp($l)"); //l for length, p for precicion, s for scale lengthprecision覆盖列的长度(取决于括号内的内容)。请注意,该方法的第二个参数定义了此特定数据类型的最大可能列长度,因此,例如纳秒精度,您应该将其更改为9。