我的User
实体类包含密码哈希字段,这是一个具有固定长度的字节数组(32,因为它是SHA-256哈希)。
@Entity
public class User {
@Column(nullable=false)
private byte[] passwordHash;
...
}
正如你所看到的,我没有用任何特殊的东西注释它,只是一个NOT NULL。
这有效,但会有效吗?我的架构是由Hibernate生成的,但我不确切知道它生成了什么(我目前正在使用内存中的HSQL数据库)。
我很担心,因为它不知道它是一个固定长度的数组(length
注释的Column
字段仅适用于字符串),它会将此哈希存储在BLOB字段,它作为指针添加到记录中(如果我正确理解数据库是如何工作的)。
这是真的,我怎么能改变这个?我应该只使用base64或hex将哈希值编码为字符串,接受它的性能/正确性影响吗?
答案 0 :(得分:5)
我很担心,因为它不知道它是一个固定长度的数组(Column注释的长度字段仅适用于字符串),(...)
如果指定列长度,Hibernate将使用此信息来确定要生成的SQL列类型(TINYBLOB
,BLOB
,MEDIUMBLOB
,LONGBLOB
)。
我需要的是BINARY(32)
你试过这个吗?
@Column(columnDefinition="BINARY(32) NOT NULL")
private byte[] passwordHash;
答案 1 :(得分:1)
tinyblob是一个很好的玩笑(mysql types reference),但我的所有应用程序都适用于Strings。 如果您真的关心毫秒,请在分析器中尝试两个版本并查看最佳效果。我首选的分析器是netbeans中包含的分析器。
答案 2 :(得分:0)
据我所知,SHA-256哈希始终只是可打印字符(如果不是,则将其编码为base64),因此解决方案是您可以将其存储为字符串,然后使用length
字段Column
注释。
然后你有了固定的长度,毫无疑问的表现。
答案 3 :(得分:0)
它可能效率不高,但我建议您使用String作为存储类型,并根据需要使用getter和setter方法进行转换。这允许不同数据库之间的JPA最大可移植性。
我使用与日期/时间类似的技术,通过存储表示UTC时代以来的时间的长片,这样可以避免时区问题(时区信息在所有数据库的数据库日期都不可移植)。