merge() 方法的细微差别
如果你想使用 Hibernate 来改变一个已经存储在数据库中的对象,那么也有几种方法可以做到这一点。
第一个是merge()方法,它根据传递的对象更新数据库中的信息。这将调用 SQL UPDATE 查询。例子:
User user = new User();
user.setName("Kolyan");
session.save(user);
session.evict(user); // detach the object from the session
user.setName("Masha");
User user2 = (User) session.merge(user);
这里有几个重要的细微差别。
首先,merge()方法返回结果,即更新后的对象。该对象具有 Persist 状态并附加到会话对象。传递给merge()方法的对象不会改变。
user 和 user2 之间似乎没有区别,但事实并非如此。您可以将一个 POJO 对象传递给merge()方法,结果,该方法可以返回一个代理(取决于 Hibernate 设置)。所以请记住merge()方法不会更改传递的对象。
其次,如果传递给merge()的对象具有 Transient 状态(并且它没有 ID),那么将在数据库中为其创建一个单独的行。换句话说,将执行persist()命令。
第三,如果一个已经附加到会话的对象(具有 Persist 状态)被传递给merge()方法,那么什么也不会发生——该方法将简单地返回同一个对象。为什么?这一切都是因为当事务被提交时,数据无论如何都会被写入数据库:
User user = new User();
user.setName("Kolyan");
session.save(user);
user.setName("Masha"); //change the object attached to the session
session.close(); //all changed objects will be written to the database
每次更改后都不需要保存对象。如果这个对象处于 Persist 状态,那么 Hibernate 会自己做所有事情。如果更改“附加到基础”的对象,则其所有更改都将写入基础。
update() 方法的细微差别
Hibernate 也有一个update()方法,它和save()方法一样,是从以前的版本继承而来的。使用此方法,您只能更新已保存对象的数据。这将调用 SQL UPDATE 查询。例子:
User user = new User();
user.setName("Kolyan");
session.save(user);
session.evict(user); // detach the object from the session
user.setName("Masha");
session.update(user);
此方法不返回任何内容,也不更改现有对象。
如果您在一个新对象上调用此方法,则会抛出一个异常:
User user = new User();
user.setName("Kolyan");
session.update(user); //an exception will be thrown here
saveOrUpdate() 方法
在JPA出现之前,persist()方法的功能是由saveOrUpdate()方法完成的。他的任务是更新数据库中现有对象的信息,如果没有,则创建它。它几乎总是用来代替save()和update()方法。
与update()方法不同,它可以更改传递给它的对象。例如,将其设置为保存到数据库时分配的 ID。例子:
User user = new User();
user.setName("Kolyan");
session.saveOrUpdate(user); //object will be written to the database
怎么运行的:
- 如果传递的对象有 ID,则调用 UPDATE SQL 方法
- 如果未设置传递对象的 ID,则调用 INSERT SQL 方法
GO TO FULL VERSION