我的日常

登录/注册
您现在的位置:论坛 盖世程序员(我猜到了开头 却没有猜到结局) 盖世程序员 > session.merge ()跟session.save()、session.update () ...
总共48087条微博

动态微博

查看: 4545|回复: 0

session.merge ()跟session.save()、session.update ()方法的区别

[复制链接]
admin    

1244

主题

544

听众

1万

金钱

管理员

  • TA的每日心情

    2021-2-2 11:21
  • 签到天数: 36 天

    [LV.5]常住居民I

    管理员

    跳转到指定楼层
    楼主
    发表于 2015-05-19 15:31:52 |只看该作者 |倒序浏览
    该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,也即该实体依然是脱管状。. o$ a+ `* a/ ^% I/ ]) ]! {' r% z
    session.merge ()方法对状态的变化) D3 B7 u, M' I2 a
    3 T( b2 ^* t7 w0 t9 w, o3 V+ i
         public void run() {, f8 @% r# m% {2 n' O8 Z* w) y  z
    ) M/ J4 [* T! y- v8 y8 [
              //创建UserInfo实例$ C' ?" N) Y" E

    " n6 X- a. g' W9 L7 m: ^- `% J          UserInfo userInfo = new UserInfo();
    8 {: V$ U0 f; j! o7 `$ V3 v1 r. V% c, \) X! B
              //使之成为脱管状态* N6 u+ H6 [9 }; v4 b. @

    + v& U& Y9 [; _/ B2 N" O1 b          userInfo.setId(11112);8 C' M5 z1 D3 V- J' L. L: g0 X
    ; R. f4 Z* U" d* m
              userInfo.setName("RW3");9 |. Z; e& P: o* g" S7 w
    8 D# s% ?$ n$ r, `' |
              userInfo.setSex("M");
      O4 |9 a! w# U: d6 I+ B7 l
    # J% f- m6 y. x) n. Y          //创建UserInfo实例* J( l5 d/ |1 T% m; {6 ~

    ' e5 v8 ?3 M% w: g- U- R% A! X          UserInfo userInfo2 = new UserInfo();* A5 B: L+ a! o  M1 ~
    , d/ C+ Z6 `* ~  [
              //使之成为脱管状态
    4 u  X9 d8 Z( j* n+ u/ A; z- V, F0 b& i" v1 h* |
              userInfo2.setId(11112);
    . `' C+ V' a  J  }( o  I6 R2 f* c2 ]' }: ^: l
              userInfo2.setName("RW4");
    . `: q5 g; }/ c/ L& e6 a7 w7 H; y1 w1 j& f
              userInfo2.setSex("F");& c6 u# g9 d( _8 E3 H: u
    & P7 [* Q% A- F* O
              //启动Session2 |0 P) l" ?5 V+ K& d/ }6 [/ o: @
    # h3 E3 g1 r3 ~
              Session session = hibernateSessionFactory.currentSession();
    9 F% n9 m% ~; z3 h, P" H. A! p9 |  g* l* C. y( |1 }; @
              //启动事务
    . \1 B* I1 Z4 H: O' p- T% r5 ~, [  p( {
              Transaction tx = session.beginTransaction();
    3 k0 V" t5 |7 y, C( n2 a+ R
    * T6 e! o2 j5 p; L$ m" a          //调用merge方法,此时UserInfo实体状态并没有被持久化6 J5 j, r% ~3 Z9 v/ Q
    / b$ ]1 |( a/ k# S
              session.merge(userInfo);  [4 J2 o" k$ f3 t
    3 d7 U% }; y* i4 p# G2 Y
              //调用merge方法,此时UserInfo实体状态并没有被持久化
    9 [( l+ l* F" l) S- x+ [2 }1 l7 M" ]" h
              //但是数据库中的记录被更新了, }1 d/ R" S9 Z8 ?0 @0 Q4 H

    4 l6 h: d0 C7 q          ①session.merge(userInfo2);6 I" N  v/ Q. e2 U) W

    ! c' V3 Y$ b% `          //merge方法与update方法的差别在于针对同样的操作update方法会报错
    ! i& D/ M5 T0 `& G# s+ T- b. _8 `# s; H  Q
              //原因在于update方法使得实体状态成为了持久化状态,而Session中不允许两个持久化实体有同样的持久化标识
    ! e& r( f) q1 w2 H; {" ?) M- y* X% Y
              ②//session.update(userInfo);7 _% Q! a; G0 H
    + v% e. q# F+ `3 W2 [
              //session.update(userInfo2);
    9 |: N6 `* N- K4 d+ G3 d; ?* F3 h# X: G7 p
             //以下两句不会发送SQL,因为userInfo2不是持久化状态的实体* Z- x: ]! w6 b) S

    2 m) {+ k5 L6 W* O         ③userInfo2.setName("RW5");
    . E' i4 x' |' \( {& N) A
    , u7 U6 @/ [) G( ^9 P! q          userInfo2.setSex("M");
    7 B, ]) W+ J* F$ ]1 e5 c0 Y4 n% P( T
              //提交事务4 ^$ y, \* z/ b2 G! k

    1 q' }& M" r9 d4 K5 c          tx.commit();* `* i. u1 v3 v. u2 l

    & g/ f% T; F$ C% B          //关闭Hibernate Session
    & w% g: W9 B6 B, ]( \! P; G% c- P0 T0 K( J
              HibernateSessionFactory.closeSession();
    5 X" {! j) B# a" T( Q, d* Q# u5 e9 r; x  w8 ^1 y( R! H, L: ^
         }4 }- J8 F0 M% s- X( @( y

    3 \" ~2 D% v9 ^+ j针对该段代码将执行如下SQL语句:
    ) N* s- H( y. f+ X3 f9 s' r- \+ f: B1 r: ^8 j, e
    Hibernate:0 Q7 I/ |0 _; B" W) j: i- {, j
    ' F" P5 n' V& g# U4 U
    /* ①session.merge(userInfo2)的动作 */% [" }( N9 t8 e, Y7 y  {

    3 o- |7 e4 ^9 l1 l6 j2 `) jselect
    ( B6 X, d# h# `* S5 u* V: C+ T. R  @2 B* M
            userinfo0_.id as id0_0_,# ?5 T: W& w6 F

    5 i% V) V7 p% O0 s: y, W        userinfo0_.NAME as NAME0_0_,
    1 k$ Q% u" o  ~" {# v* r! K2 p5 p4 f# u: D! ~  k6 S' Q, L5 f! m3 \4 a
            userinfo0_.SEX as SEX0_0_,
    % u% X7 r% I  \4 u* i& x" {- U2 D4 V8 A4 D0 O3 F7 q
            userinfo0_.roomid as roomid0_0_
    ( R5 w0 y, B, x, E; C1 z
    6 |) p  T% m& l, q  t2 l! W    from
    % q! n; I8 p/ k1 q5 U3 g- \8 {
    - N! M- |$ W" h5 ~/ d' L        userinfo userinfo0_
    6 x! b5 o; }7 v, U& F) f
    3 S0 j+ x. T! e  h    where
    + N2 Z8 Z% J" c0 I' ~1 a1 r' @
    / L! I1 j$ f' e        userinfo0_.id=?
    . a6 W. Y' Z7 \, @1 R4 a* B( u3 W+ z0 v: h1 t0 s
    Hibernate:
    " b2 G2 i  k: C  G8 R9 K
    . z0 e: B' h% o8 s* K/* ①session.merge(userInfo2)的动作 */0 Z$ x  D0 k0 T6 ?
    * J" s! s) Q; d. @, L
    update- m' k1 i. W% a" e* H3 ~' {. L8 K
    $ D& g8 D1 ?* N% f
                userinfo
    1 u. g6 [8 @% R& j
    8 B- L" s( S9 v9 w7 n% a5 Z! O+ X        set( x; Y$ P: F- o8 r6 l; T5 g+ _
    9 I3 d) ]& c9 I; Y+ \2 V
                NAME=?,5 z# l+ `7 G$ c, E0 y& h: ]

    8 C) m  x3 e9 \- Y: p            SEX=?,
    7 X* ~1 i3 ^0 @6 X7 Q$ X9 Z* Z: z* u- K. H" U% z; q1 s
                roomid=?- Q& o' O8 p, Q9 G! B9 X1 G) B

    9 C& y# ]) M8 {, P        where
    $ ?8 |& v6 h3 `- z/ ^
    9 _6 Q0 Q+ l4 P* j  i# _            id=?: B4 u: c6 n/ l. Q. K- u

    ) k4 w( l. A+ E" k' b" Jsession.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,那其结果只会执行最后一个session.merge()方法所发出的update语句。即使执行了session.merge()方法,UserInfo实体依然是脱管状态,因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。
    - m! S- q" R5 W9 \+ m( i; z# Q" W& c: C% ^# ^

    科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、科帮网管理员和版主有权不事先通知发贴者而删除本文


    JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

    快速回复
    您需要登录后才可以回帖 登录 | 立即注册

       

    关闭

    站长推荐上一条 /1 下一条

    发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
    快速回复 返回顶部 返回列表