Hibernate的save()方法如何判断是insert还是update

Hibernate的save()方法如何判断是insert还是update

之前大概了解在使用save()方法的时候,要是执行更新操作,就先查再调用save();要是执行插入操作,就新建一个对象,将属性赋值,再调用save()方法。
今天研究了下save方法的源码,如下

 public T save(T entity) throws DataAccessException {
        if(entity.isNew()) {
            this.preInsert(entity);
        } else {
            this.preUpdate(entity);
        }

从源码可以看出,根据entity.isNew()来判断是执行插入还是更新

 public boolean isNew() {
        return this.getId() == null;
    }

如果当前对象的主键ID为null,就执行插入操作,否则执行更新

由此我们就可以灵活的使用save()方法了,之前博客有提到过,spring data jpa自动执行update的问题,我们可以把查询出来的处于持久态的实体copy给一个新的实体,再对属性进行修改,则不会触发update,但是需要注意的是,你的实体属性里面是否有主键ID的属性,如果没有,copy后的新实体的主键ID为null,会调用insert。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要在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); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值