TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,也即该实体依然是脱管状。6 ]8 d ~% N/ W
session.merge ()方法对状态的变化
% a1 x6 j+ [+ t% ]) _# k* S) x8 g$ ~5 W' N* `
public void run() {; d7 P6 P) b7 W& F2 t
0 h7 h# W8 j; h* e! H: @ E' j
//创建UserInfo实例
7 y. j8 n* C( S2 i0 d8 t0 ]8 c8 C1 j; t3 B
UserInfo userInfo = new UserInfo();
) J# {0 h/ f! }' X& Y5 |
/ U0 b5 z; m8 }0 ^, |) w //使之成为脱管状态 U+ \9 Z& e! D: `' M; \4 A/ K
0 f' }- I7 D4 N3 u userInfo.setId(11112);
5 _. v& {. i$ w; n. } P3 Z( @; o+ b
' Z& k! w' y s userInfo.setName("RW3");
8 u/ Q: y1 b" n% m) i* E9 p% }* e5 q3 a6 m) Y
userInfo.setSex("M");" s% Y5 P" [- ` F
, T p9 H( _, ]1 s2 t+ N //创建UserInfo实例: F- e7 T) R# O+ d$ F. R' n
7 D& t8 j) B9 v* h: N0 H
UserInfo userInfo2 = new UserInfo();$ m" q' g; p) I- B
' j9 W8 F# W- `3 B //使之成为脱管状态
- f5 V( V2 p8 _. p% x& r! `9 i4 Y+ b" b9 h
userInfo2.setId(11112);. X9 n' S/ k6 o( M3 M! l6 F' b
6 o) E8 p( Y* G. K4 ?
userInfo2.setName("RW4");
) L8 `- o7 O- X* o0 _
' @8 V7 ?9 s8 a" Y( _' y userInfo2.setSex("F");& q6 a: [3 ]1 e) L# J0 j
% ^$ Z4 }0 X; y3 k: D3 L) s2 l
//启动Session2 U9 `8 s, K& |) Q* N0 c
1 L& T0 q Z7 K' K Session session = hibernateSessionFactory.currentSession();6 V$ i/ {% h* v$ h9 Q
. q4 ^6 |& Y1 l5 t% g' s- H& K
//启动事务$ d" ~( f f9 n* M6 M; ^% U) Y
2 ^# x- I2 S' w" b: |7 y Transaction tx = session.beginTransaction();$ x6 y1 k) n8 ?$ i. r: t3 _
1 `7 m, q- h- K. D) Z9 | //调用merge方法,此时UserInfo实体状态并没有被持久化: Z6 C' Q* m+ p# H( N* z
9 n; c& V/ ]- C0 ^* q( D session.merge(userInfo);
0 c) z# O- ]5 ^0 ^/ B- p) |# j6 T
//调用merge方法,此时UserInfo实体状态并没有被持久化; i o# E8 K* u& l9 P8 A" c
5 ~) L3 {, }( D3 ^4 p& |
//但是数据库中的记录被更新了
( g3 m3 d3 }- U2 k% |8 B6 Z7 n4 u; g+ Y' e r
①session.merge(userInfo2);
; g/ Z" Z' g d: W6 D! [/ B% V, m. }
//merge方法与update方法的差别在于针对同样的操作update方法会报错3 l; z; Z' Z! t/ S/ Q7 C& C
9 E5 t: n5 h5 a9 W$ \1 }
//原因在于update方法使得实体状态成为了持久化状态,而Session中不允许两个持久化实体有同样的持久化标识) U3 g/ J( A) @* e* \. {
4 _' A6 X2 J% s* G# D' Z1 i% i* d
②//session.update(userInfo);
`8 a% v# u: ^' F8 c0 @1 O7 q& R- c
//session.update(userInfo2);3 [: K% @# ~2 v* g3 J! i+ _0 L
$ N( P7 L, X- N
//以下两句不会发送SQL,因为userInfo2不是持久化状态的实体
% d: ^% }5 B6 O' |' V4 ]) J4 G/ n1 I7 q
③userInfo2.setName("RW5");
) B# ?) l* L8 ]! X
: y1 j) n. n1 |. p5 b/ k7 e( ` userInfo2.setSex("M");
" v @, h9 d" u9 w8 l+ w! b2 L( g9 h9 A# Y& W; _+ u1 W
//提交事务
9 Y: u# ?: F8 a) F% a0 J2 e: O9 @" o# D9 J8 N# z( b
tx.commit();
! \, _& u I1 e3 A9 u" O# N2 i. f5 a2 Q/ n% m7 P6 f. I0 y) O, F" O
//关闭Hibernate Session; i! [/ ^6 p& `: E3 r: \+ E" x
- M6 D$ f: {! k! r HibernateSessionFactory.closeSession();
: D6 J, u& K9 ?/ @5 l+ |
2 J ` z, p z. P8 \ }6 H7 F, ~6 l9 F- m: n+ `
1 U, I$ Q/ u, N, T2 W8 Y+ I& J
针对该段代码将执行如下SQL语句:
y3 `$ t1 P$ l2 q; H0 q, l9 B4 ?7 B" _6 k, V& t
Hibernate:
8 }+ V7 M. A9 t. F" q, J
1 t0 W! u% a- S9 L* }; `' d% M" H/* ①session.merge(userInfo2)的动作 */
5 m) D+ V$ ^" f6 T# m& ]0 [. F& h9 f, ~3 a3 E @7 V C- [
select
. T& a# E6 K% ~+ W% B
4 ^ w5 e# p% j6 S; \; ] userinfo0_.id as id0_0_,! v6 e) _3 G0 ~
' W. |4 }8 o$ p; G userinfo0_.NAME as NAME0_0_,
. @- _8 V: o5 e$ c& I( L, S: M- z( M5 d8 P( s
userinfo0_.SEX as SEX0_0_,
- Y8 `1 w2 z& C5 t5 z
8 m; z y4 r0 N; C" E userinfo0_.roomid as roomid0_0_$ X$ S# D& k0 `! M
9 b; h F6 J3 |9 E6 s: |
from
! p( F, t: ]5 J1 q6 d3 I+ c
, y9 N5 B( k2 U- |! K- Z5 F3 u/ f userinfo userinfo0_" m/ {# X% G* w8 ]( \- t
3 S8 t; C2 \$ K# w where3 {7 ]0 T1 V/ _8 w
) `% {1 Y4 l5 U: ]# p2 ~" c/ y userinfo0_.id=?
2 F1 T; O( b3 B' ~5 |( ]) w8 D' `& d* X3 ^8 d
Hibernate:
, Z! o) Z: _+ G; b8 n. I
* G% v) |0 L+ _% v2 d$ q6 w6 g/* ①session.merge(userInfo2)的动作 */
1 k3 l. t' @! D+ l( ~. F+ d/ g
# E: f, c, D$ K. `2 c' P+ e! supdate
& Z# Y- M0 Y/ Z1 _
+ W) s! w2 E' K, p userinfo3 e- ^& t3 |4 H7 ^. M
% p& X8 S& Q, W: B( U8 T1 o
set
% b! n, k( t; l
$ U8 U) n% W1 ^* G2 n4 J1 S3 j NAME=?,
9 n/ f& Z! P7 N. ~/ e) ]3 }
1 |# K/ I3 j' \& S m7 V! V e SEX=?,
8 i+ K- k( Z: p, k/ u. \% ~0 x, T' i: o J1 G
roomid=?7 f$ u5 ]: e) ^3 d5 l: D* }
O; t3 M3 s/ e1 {1 t* r8 ]% n: j. P) ]
where
( n; u! P9 x1 p0 \" T
9 R/ ]$ K4 G% R, B7 E id=?
$ O2 u- S. y/ z6 ]& A( G5 F
% j0 o# l" U' Zsession.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,那其结果只会执行最后一个session.merge()方法所发出的update语句。即使执行了session.merge()方法,UserInfo实体依然是脱管状态,因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。
4 j7 R# h+ x9 c' `& k3 i8 b1 y$ \. p) ~4 F
|
|