我试图保存用户的详细信息到用户表,但与一些列有加密的数据,但我仍然想使用他们解密后的代码。例如:用户的详细信息有用户名,我加密并存储在表中。但我想使用用户名解密后。
为了实现这一点,我在bean的setter中添加了加密用户名的代码,并在getter中添加了解密值的代码,如下所示
@Table
@Entity
class User {
private String username;
private int age;
@Column
public String getUsername(){
return Commons.decrypt(this.username);
}
@Column
public int getAge(){
return this.age;
}
public void setUsername(String username){
this.username = Commons.encrypt(username);
}
public void setAge(int age){}
this.age = age;
}
字符串
在保存User表中的值时,我使用javax.persistence.EntityManager
类的persist
方法,代码如下所示
UserDetails user = new UserDetails();
user.setUsername("User 1");
user.setAge(31);
entityManager.persist();
型
我期望代码执行如下
1.当通过setter
设置username时,它应该加密值
1.当调用persist
方法时,加密值必须保存在数据库中
1.从数据库中获取数据时,应该具有加密的用户名值
1.在调用getter
方法时,它应该解密并返回解密的用户名
但问题是,只要我调用persist
方法,hibernate
就会在内部调用getter
和setter
方法n次,最终导致在数据库中保存解密值,即User 1
而不是eytsnkcjsdvnfsnvkscd=
,因此,当我试图从DB中获取数据时,会返回解密值,并且getter
中的Commons.decrypt(this.username)
失败。
如何通过一个通用的代码策略来实现上述期望,我在getter和setter中尝试,因为大多数代码已经编写并正在使用它。
2条答案
按热度按时间yr9zkbsy1#
对于Spring Data,通常使用
Repository Interface
并使用AttributeConverter
进行加密。下面是一个
AttributeConverter
example by sultanov.dev:字符串
然后,实体
User
将只包含基本的数据字段和getter/setter方法(简称为Lombok)以及用户名的@Convert
注解。型
@Column
注解用于当实体中的属性从辅助表中提取时,其中table属性标识相应的表。我不确定您试图将getter方法标记为列来实现什么。对存储对象的访问通常使用Sping Data的Repository接口之一来实现,例如
JpaRepository
。型
在您的服务层中,您应该能够使用来自存储库的数据,并自动处理加密。
型
7vux5j2d2#
你面临的问题是由于Hibernate在持久化和检索过程中与实体getter和setter交互的方式。Hibernate使用getter和setter访问实体属性,在你的情况下,这会导致无意中的解密和重新加密。
要解决此问题,您可以执行以下步骤:
1.数据库和域模型分离:您可以引入一个单独的域模型类,而不是直接在
User
实体的getter和setter中进行加密和解密,这个类将代表您的数据的解密版本,用于应用逻辑中。1.使用@ PrePersists和@PostLoad Annotations:使用这些Annotations在getter和setter之外处理加密和解密。这可以确保数据在持久化之前加密,从数据库加载后解密,而不会干扰标准的getter/setter行为。
*重构实体类:
username
作为普通字符串保存在User
实体中。@PrePersist
加密用户名。@PostLoad
解密用户名。以下是如何重构
User
实体:字符串
在这一办法中:
@PrePersist
方法encryptFields
,确保username
在数据库中加密。@PostLoad
方法decryptFields
,解密username
以供应用程序使用。这样,标准的getter和setter不受影响,加密/解密在持久化和检索阶段被透明地处理。这种策略应该可以满足您对存储数据加密的需求,同时仍然可以在代码中使用解密的数据。