您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > session中merge和update的区别
session的update与merge方法标签:杂谈Hibernate的merge方法,按照hibernate对象生命周期的三个状态来讲。1:如果POJO对象处于游离态,我所说的游离态是指该对象的id值为空。hibernate判断一个对象在数据库中是否存在不是看对象的其他信息,而是判断该id在数据库中是不是存在。如果id为空,那自然是不存在,所以当我们调用merge方法的时候,就会直接执行插入操作。这一点有点像saveorupdate()方法。看一段代码:Java代码Useruser=newUser();//user.setId(4);user.setUsername(heyuanling2);user.setAge(23);user.setSex(w);user.setPassword(heyuanling);Sessionsession=this.getSession();Transactiontr=session.beginTransaction();//Userexituser=(User)session.get(User.class,newInteger(1));session.merge(user);tr.commit();再看hibernate的sql语句:Java代码Hibernate:selectmax(id)fromuser_Hibernate:insertintouser_(username,password,sex,age,birthday,other,id)values(?,?,?,?,?,?,?)二:脱管态:如果我们把上面代码里//user.setId(4);的注释去掉,那么它就变成了脱管的对象了(其实从游离到脱管就这么简单,没有官方说的那么邪乎...)。这是我们再来看控制台的sql打印:Java代码Hibernate:selectuser0_.idasid4_0_,user0_.usernameasusername4_0_,user0_.passwordaspassword4_0_,user0_.sexassex4_0_,user0_.ageasage4_0_,user0_.birthdayasbirthday4_0_,user0_.otherasother4_0_fromuser_user0_whereuser0_.id=?看到没有,因为id不为空了,所以hibernate就不会再insert了。由于该对象的信息和数据库里的一模一样,所以hibernate只执行了一个select语句,并没有update,如果我们把字段的值做稍微的变动,那么控制台打印的sql语句还应该有一条update语句。就这一点来说,merge还有和saveorupdate()方法一样。三:持久态:持久态更好理解。如果我们从数据库里get一条记录,那么这条记录就处于持久态,如果再调用merge,那么hibernate就会先判断该记录是否被修改,没有则什么也不干,修改了就update。这一点还是和saveorupdate()有点像。Java代码Sessionsession=this.getSession();Transactiontr=session.beginTransaction();Userexituser=(User)session.get(User.class,newInteger(1));exituser.setAge(11);session.merge(exituser);tr.commit();session.close();再看控制台打印结果:Java代码Hibernate:selectuser0_.idasid4_0_,user0_.usernameasusername4_0_,user0_.passwordaspassword4_0_,user0_.sexassex4_0_,user0_.ageasage4_0_,user0_.birthdayasbirthday4_0_,user0_.otherasother4_0_fromuser_user0_whereuser0_.id=?Hibernate:updateuser_setusername=?,password=?,sex=?,age=?,birthday=?,other=?whereid=?如果没有对记录进行修改则不会有后面的那条update语句。那么merge和saveorupdate()到底有什么区别呢?看一段代码:Java代码Sessionsession=this.getSession();Transactiontr=session.beginTransaction();Userexituser=(User)session.get(User.class,newInteger(1));tr.commit();session.close();session=getSession();tr=session.beginTransaction();Userexituser2=(User)session.get(User.class,newInteger(1));session.update(exituser);tr.commit();session.close();运行上面的代码,hibernate给我们报了一个错误:adifferentobjectwiththesameidentifiervaluewasalreadyassociatedwiththesession。意思是,在session缓存中以两个标识相同的对象,这是不可以的。那么,吧update改成merge会怎么样呢?改为merge后,一切OK,运行正常。其实merge在执行更新之前会将两个标识符相同的对象进行合并,具体合并的方向是向exituser2合并。注意:merge方法在执行之前都回去缓存中找是不是有相应的记录,也就是会有一条select语句,执行改语句的目的是为了判断该对象是否被修改了。而update就不管这些,直接就一条update语句。
本文标题:session中merge和update的区别
链接地址:https://www.777doc.com/doc-2849381 .html