我有一个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
自变量是否可行。
答案 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
,length
或precision
覆盖列的长度(取决于括号内的内容)。请注意,该方法的第二个参数定义了此特定数据类型的最大可能列长度,因此,例如纳秒精度,您应该将其更改为9。