在java 的hibernate框架中,我有一个User类,其中有一个SealedObject 类型的属性 password,用来保存内存加密的用户密码,该属性的get方法是把SealedObject解密,转为字符串。数据库对应的user表中password的字段类型为varchar,我想利用hibernate的save方法把这个对象保存到数据库,我该如何配置hibernate,从而使我调用save方法的时候把SealedObject加密的原始密码保存到数据库中
时间: 2024-02-03 21:11:33 浏览: 147
首先,你需要在User类中添加一个用于保存加密密码字符串的字符串类型属性,例如:encryptedPassword。在该属性的set方法中,将传入的密码字符串加密并保存到password属性中。
然后,在Hibernate的映射文件中,你需要将password属性映射为数据库中的varchar字段,同时在保存时,使用encryptedPassword属性的值进行保存。
以下是一个示例映射文件:
```
<class name="com.example.User" table="user">
<id name="id" type="long">
<generator class="native"/>
</id>
<property name="username" column="username" type="string"/>
<property name="password" column="password" type="sealed_object"/>
<property name="encryptedPassword" column="password" type="string" insert="false" update="false"/>
</class>
```
在上面的映射文件中,password属性被映射为自定义的sealed_object类型,encryptedPassword属性被映射为varchar类型,并且在保存时不会更新到数据库中。这样,当你使用Hibernate的save方法保存User对象时,encryptedPassword属性的值会被忽略,而password属性的值会被加密后保存到数据库中。
注意,你需要自定义一个Hibernate类型,来将SealedObject类型映射为数据库中的类型。以下是一个示例自定义类型:
```
public class SealedObjectType implements UserType {
private static final int[] SQL_TYPES = {Types.BLOB};
@Override
public int[] sqlTypes() {
return SQL_TYPES;
}
@Override
public Class returnedClass() {
return SealedObject.class;
}
@Override
public boolean equals(Object o, Object o1) throws HibernateException {
return Objects.equals(o, o1);
}
@Override
public int hashCode(Object o) throws HibernateException {
return Objects.hashCode(o);
}
@Override
public Object nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException, SQLException {
Blob blob = resultSet.getBlob(strings[0]);
if (blob == null) {
return null;
}
try (ObjectInputStream ois = new ObjectInputStream(blob.getBinaryStream())) {
return ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new HibernateException(e);
}
}
@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object o, int i, SharedSessionContractImplementor sharedSessionContractImplementor) throws HibernateException, SQLException {
if (o == null) {
preparedStatement.setNull(i, Types.BLOB);
} else {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(o);
oos.flush();
byte[] bytes = baos.toByteArray();
preparedStatement.setBinaryStream(i, new ByteArrayInputStream(bytes), bytes.length);
} catch (IOException e) {
throw new HibernateException(e);
}
}
}
@Override
public Object deepCopy(Object o) throws HibernateException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new HibernateException(e);
}
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object o) throws HibernateException {
return (Serializable) o;
}
@Override
public Object assemble(Serializable serializable, Object o) throws HibernateException {
return serializable;
}
@Override
public Object replace(Object o, Object o1, Object o2) throws HibernateException {
return o;
}
}
```
在上面的示例中,我们使用Blob类型将SealedObject对象保存到数据库中,并实现了自定义类型的相关操作。你需要将这个类型添加到Hibernate的配置文件中,例如:
```
<property name="hibernate.type_contributors">com.example.SealedObjectTypeContributor</property>
```
其中,SealedObjectTypeContributor是一个自定义的TypeContributor,用于注册我们自定义的类型。
最后,你需要在代码中使用Hibernate的save方法保存User对象,例如:
```
User user = new User();
user.setUsername("test");
user.setEncryptedPassword("123456");
session.save(user);
```
阅读全文