下面来讲讲Hibernate的merge方法。我打算按照hibernate对象生命周期的三个状态来讲。
1:如果POJO对象处于游离态,我所说的游离态是指该对象的id值为空。hibernate判断一个对象在数据库中是否存在不是看对象的其他信息,而是判断该id在数据库中是不是存在。如果id为空,那自然是不存在,所以当我们调用merge方法的时候,就会直接执行插入操作。这一点有点像saveorupdate()方法。看一段代码:
User user = new User();
//user.setId(4);
user.setUsername("heyuanling2");
user.setAge(23);
user.setSex("w");
user.setPassword("heyuanling");
Session session = this.getSession();
Transaction tr = session.beginTransaction();
//User exituser = (User)session.get(User.class, new Integer(1));
session.merge(user);
tr.commit();
再看hibernate的sql语句:
Hibernate:
select
max(id)
from
user_
Hibernate:
insert
into
user_
(username, password, sex, age, birthday, other, id)
values
(?, ?, ?, ?, ?, ?, ?)
二:脱管态:如果我们把上面代码里//user.setId(4);的注释去掉,那么它就变成了脱管的对象了(其实从游离到脱管就这么简单,没有官方说的那么邪乎...)。这是我们再来看控制台的sql打印:
Hibernate:
select
user0_.id as id4_0_,
user0_.username as username4_0_,
user0_.password as password4_0_,
user0_.sex as sex4_0_,
user0_.age as age4_0_,
user0_.birthday as birthday4_0_,
user0_.other as other4_0_
from
user_ user0_
where
user0_.id=?
看到没有,因为id不为空了,所以hibernate就不会再insert了。由于该对象的信息和数据库里的一模一样,所以hibernate只执行了一个select语句,并没有update,如果我们把字段的值做稍微的变动,那么控制台打印的sql语句还应该有一条update语句。就这一点来说,merge还有和saveorupdate()方法一样。
三:持久态:持久态更好理解。如果我们从数据库里get一条记录,那么这条记录就处于持久态,如果再调用merge,那么hibernate就会先判断该记录是否被修改,没有则什么也不干,修改了就update。这一点还是和saveorupdate()有点像。
Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
exituser.setAge(11);
session.merge(exituser);
tr.commit();
session.close();
再看控制台打印结果:
Hibernate:
select
user0_.id as id4_0_,
user0_.username as username4_0_,
user0_.password as password4_0_,
user0_.sex as sex4_0_,
user0_.age as age4_0_,
user0_.birthday as birthday4_0_,
user0_.other as other4_0_
from
user_ user0_
where
user0_.id=?
Hibernate:
update
user_
set
username=?,
password=?,
sex=?,
age=?,
birthday=?,
other=?
where
id=?
如果没有对记录进行修改则不会有后面的那条update语句。
那么merge和saveorupdate()到底有什么区别呢?看一段代码:
Session session = this.getSession();
Transaction tr = session.beginTransaction();
User exituser = (User)session.get(User.class, new Integer(1));
tr.commit();
session.close();
session = getSession();
tr = session.beginTransaction();
User exituser2 = (User)session.get(User.class, new Integer(1));
session.update(exituser);
tr.commit();
session.close();
运行上面的代码,hibernate给我们报了一个错误:a different object with the same identifier value was already associated with the session。意思是,在session缓存中以两个标识相同的对象,这是不可以的。那么,吧update改成merge会怎么样呢?改为merge后,一切OK,运行正常。其实merge在执行更新之前会将两个标识符相同的对象进行合并,具体合并的方向是向exituser2合并。
注意:merge方法在执行之前都回去缓存中找是不是有相应的记录,也就是会有一条select语句,执行改语句的目的是为了判断该对象是否被修改了。而update就不管这些,直接就一条update语句。
分享到:
相关推荐
Hibernate merge、update与saveOrUpdate方法的区别
Hibernate中的merge使用详情解说
merge的作用是:新new一个对象,如果该对象设置了ID,则这个对象就当作游离态处理: 当ID在数据库中不能找到时,用update的话肯定会报异常,然而用merge的话,就会insert。 当ID在数据库中能找到的时候,update与...
NULL 博文链接:https://dreamzhong.iteye.com/blog/1218885
Hibernate中session的merge以及update方法
还行吧 关于hibernate中更新 操作的注意事项
我身边的朋友经常会分不清save、saveOrUpdate、update的区别,lock、merge、replicate、refresh、evict甚至不知道是干什么用的。而且关于实体对象的生命周期也有很多概念不清,分不清transient、persistent、...
8.4.5 Session的merge()方法 8.4.6 Session的delete()方法 8.4.7 Session的replicate()方法 8.5 级联操纵对象图 8.5.1 级联保存临时对象 8.5.2 更新持久化对象 8.5.3 持久化临时对象 8.5.4 更新游离...
根据注释可以知道 merge 有两个职责: 1.如果对象为 unsaved,对对象的拷贝执行 save 方法,返回拷贝的对象。 2.如果对象为 detached,将对象的状态拷贝到和对象的标识一样的持久化对象中,如果持久化对象不存在,就...
8.4.5 Session的merge()方法 198 8.4.6 Session的delete()方法 200 8.4.7 Session的replicate()方法 201 8.5 级联操纵对象图 202 8.5.1 级联保存临时对象 206 8.5.2 更新持久化对象 207 8.5.3 持久化临时对象 ...
* 9.increnment 插入数据的时候hibernate会给主键添加一个自增的主键,但是一个hibernate实例就维护一个计数器,所以在多个实例运行的时候不能使用这个方法。 * 例:@GeneratedValue(generator = ...
Hibernate 可以对类的属性或者方法进行注解。属性对应field类别,方法的 getXxx()对应property类别。 定义表 通过 @Table 为实体Bean指定对应数据库表,目录和schema的名字。 @Entity @Table(name="tbl_sky") ...
8.4.5 Session的merge()方法 198 8.4.6 Session的delete()方法 200 8.4.7 Session的replicate()方法 201 8.5 级联操纵对象图 202 8.5.1 级联保存临时对象 206 8.5.2 更新持久化对象 207 8.5.3 持久化临时对象 ...
8.4.5 Session的merge()方法 8.4.6 Session的delete()方法 8.4.7 Session的replicate()方法 8.5 级联操纵对象图 8.5.1 级联保存临时对象 8.5.2 更新持久化对象 8.5.3 持久化临时对象 8.5.4 更新游离...
8.4.5 Session的merge()方法 8.4.6 Session的delete()方法 8.4.7 Session的replicate()方法 8.5 级联操纵对象图 8.5.1 级联保存临时对象 8.5.2 更新持久化对象 8.5.3 持久化临时对象 8.5.4 更新游离...
8.4.5 Session的merge()方法 8.4.6 Session的delete()方法 8.4.7 Session的replicate()方法 8.5 级联操纵对象图 8.5.1 级联保存临时对象 8.5.2 更新持久化对象 8.5.3 持久化临时对象 8.5.4 更新游离...
示例-jpa_insert_on_merge 显示Hibernate和Eclipselink如何通过merge()表现的示例
hibernate save()方法能够保存实体到数据库,正如方法名称save这个单词所表明的意思。我们能够在事务之外调用这个方法,这也是我不喜欢使用这个方法保存数据的原因。 假如两个实体之间有关系(例如employee表和...
Hibernate Annotation几种关联映射 一对一(One-To-One) 使用@OneToOne注解建立实体Bean之间的一对一关联。一对一关联有三种情况:(1).关联的实体都共享同样的主键,(2).其中一个实体通过外键关联到另一个实体的主键...