MySQL中的列应该自动散列插入的值(使用Hibernate和Java)
我有一些Java对象,使用hibernate,例如:MySQL中的列应该自动散列插入的值(使用Hibernate和Java),java,mysql,hibernate,Java,Mysql,Hibernate,我有一些Java对象,使用hibernate,例如: @Entity class User { @Id private int id; @Column private String name; @Column private String pw; public User() {} public String getName() { return name; } public void setName(String
@Entity
class User {
@Id
private int id;
@Column
private String name;
@Column
private String pw;
public User() {}
public String getName() { return name; }
public void setName(String name) { this.name = name;}
public String getPw() { return pw; }
public void setPw(String pw) { this.pw = pw; }
}
当我实例化一个新的用户对象时,我会像这样手动散列一个字符串
User user1 = new User();
user1.setPw(hashPw("MyPassword"));
它工作得很好,但我想要的是像这样使用setter
user1.setPw("MyPassword")
我希望数据库使用SHA-512算法(或者您推荐的任何也可以在Java中使用的算法)自动对字符串进行散列
我想告诉数据库,当它被创建时,这个列必须被散列
我完全用hibernate构建了数据库,这是我的新手。
ATM I使用utf8字符集将哈希保存在char(128)列中,不可为空
编辑:
最好是在java代码中使用hibernate/jpa中的注释
编辑:
我的应用程序的第一步是用数据填充数据库。在那之后,我将只使用对象,可能不再更改它们的任何值,所以当我第一次插入真实数据(测试数据atm)时,我需要哈希步骤。我已经尝试过这样的公式注释:
// ...
@Formula("SHA2(pw,512)")
private String pw;
// ...
但在那之后,这一列就不完整了
编辑:
我将尝试展示我如何想象一个可能的解决方案:
所有这些,在我的java代码中没有任何哈希逻辑。鉴于您在同一个类中处理哈希密码和未哈希密码,您必须明确区分哈希密码和未哈希密码 定义为
@column private String pw的列
是个坏主意,因为它回避了以下问题:这是什么?这是散列密码还是未散列密码?getPw()
将返回什么?如果调用setPw(“mypassword”)代码>
因此,不要只使用名为“password”的标识符,始终使用诸如“hashedPassword”和“unhashedPassword”之类的标识符
因此,我建议:
@Column
private String hashedPassword;
public String getHashedPassword()
{
return hashedPassword;
}
public void setHashedPassword( String hashedPassword )
{
this.hashedPassword = hashedPassword;
}
public String setUnhashedPassword( String unhashedPassword ) //no getter!
{
String temp = hashPw( unhashedPassword );
setHashedPassword( temp );
}
在保存之前对拦截器进行哈希怎么样?您应该查找“@PrePersist”和“@PreUpdate”注释。使用这些,您可以确保每次将实体持久化到数据库中时,所需的列都会被散列。好的,我查看了PrePersist
和PreUpdate
注释,但在那里它用于临时属性,但我将尝试它。您应该检查@Formula
的定义,因为您完全误解了它的用例。顺便说一句,密码有一些特殊的哈希算法,比如。@PrePersist
应该可以,但是@PreUpdate
可能会导致问题。例如,当用户更新其姓名/电子邮件地址时,您不希望重新显示其密码。另一个选项是添加一个@Transient
方法,如setPwPlaintext(stringplaintext)
,该方法进行哈希运算,然后相应地设置persistent属性。我同意,拦截器
的杀伤力太大了。我上面的代码只是一个简单的例子,因为这不是我的问题(很抱歉,混乱,这里的第一个问题)。我使用的代码名称很清楚。问题是,在使用hibernate插入值或保存对象时,是否可以在数据库/hibernate站点执行此哈希操作。我将编辑我的文章,并写一个我如何想象的例子。我想我已经理解了。但是我的建议是“永远不要用魔法去做一些没有魔法也能轻易完成的事情”。散列是一个简单的操作。此外,在“hibernate端”执行此操作与将其构建到实体
类中的setter中基本相同。要在数据库端执行此操作,您需要在数据库中使用本机查询或(更可能)自定义触发器。但是,您的解决方案将依赖于特定的数据库提供程序。这就是您想要的,还是您更愿意拥有可移植的代码,可以与hibernate可以对话的任何数据库提供程序一起使用?大多数时候,可移植代码比db magic更有价值。啊,好吧,现在我明白你的观点了,谢谢。好的,是的,通常我更喜欢可移植代码,但在这个特定的项目中,我认为我们只使用我将构建一次的mysql数据库。但是当我考虑它的时候,我想当我在代码中散列密码时,它会更安全,因为散列将被发送到DB,而不是发送到DB后散列的纯文本,可能稍后它会通过internet。但是,仅就我自己的知识而言,我仍然想知道,在这种情况下,我如何使用触发器来解决我的“问题”。