TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,也即该实体依然是脱管状。
2 e' _" Q7 n/ W" w# H; r* xsession.merge ()方法对状态的变化( \! }7 R% ]1 T/ C% [$ @) Y* B. B$ d7 I
* r0 o$ y6 m1 y6 v( r
public void run() {6 R' N Z9 {2 W6 d0 f
7 N4 q, Z+ x2 O# b5 ~& O //创建UserInfo实例+ m! C/ h8 G/ T$ n$ {7 {# u5 P
8 @+ r3 z3 B$ ?6 K1 q. h8 L1 Y! y UserInfo userInfo = new UserInfo();
* J* m) S3 F9 j2 H: s4 t+ @1 G( u9 \& V' U
//使之成为脱管状态2 ~# Q& g1 s0 I4 C
- Y J1 o4 X! H
userInfo.setId(11112);2 F r; o3 Y; I W3 i9 u& ? Y
, r) ?& [0 `! O/ ]. Q/ Q
userInfo.setName("RW3");0 G3 \- w; F' H6 P- o# J
6 A$ q2 W ]9 [3 r. w5 x& Z" L userInfo.setSex("M");
' a( D, n% _ A$ V/ |$ V: p
- x9 c; _5 ]8 i: D# U) Z8 _9 O //创建UserInfo实例
! j) c A: H3 |# q! N* b3 O6 J) w; Y3 E9 j' B% s$ ~
UserInfo userInfo2 = new UserInfo();8 Z+ m' D, \/ V, [: ^; J. m9 c
/ P9 w3 L1 s& e& l" Z: o) a7 [0 R! _
//使之成为脱管状态
: x/ c. s) L" y% S
9 W/ U/ r. v$ s* Z* K* A, F: V userInfo2.setId(11112);8 n3 s2 l, C+ q+ X( [" c
9 D9 j) w4 o' M: @3 N5 W
userInfo2.setName("RW4");
* z8 ?: C# R1 j; c+ ^
7 a, l b8 ?; b5 s, b0 o( U userInfo2.setSex("F");
1 o" ^; |8 }' u4 f4 C! W, K' I: c, ~
//启动Session( Q0 k, G& @- ~0 }
* E0 X, u) i% D( R9 N Session session = hibernateSessionFactory.currentSession();# Q6 t' U' L+ A; ]" n [ k
7 ~, d1 y- t$ S/ ?$ q
//启动事务
5 \( _3 \! N; z* e) @ Y* V9 y4 ?! e" V& m) `2 a5 {: U# S
Transaction tx = session.beginTransaction();
. M+ t& b i4 R: i1 S4 D5 u- a% H3 g5 C+ _
//调用merge方法,此时UserInfo实体状态并没有被持久化- j' e2 d x% k8 @
0 a: ^9 k' ]$ F9 m7 T session.merge(userInfo);, ~+ j- r7 h! G" a n
3 |, I7 I6 b L h3 a //调用merge方法,此时UserInfo实体状态并没有被持久化
# G* W8 w4 s7 v0 J/ m; U/ G! y2 R8 Q% n8 \% |
//但是数据库中的记录被更新了
7 Y$ z2 f7 ]: f$ ?7 T# b! u
$ B. R3 W7 t1 }8 J% c7 q" |+ y$ P ①session.merge(userInfo2);, M' q; r% |) }
3 o5 y6 y) G' v- ~0 c$ J
//merge方法与update方法的差别在于针对同样的操作update方法会报错
) E T: ^% p i
0 ?' ^% ]; d7 t2 ], o- @5 I //原因在于update方法使得实体状态成为了持久化状态,而Session中不允许两个持久化实体有同样的持久化标识. E# o0 }) c" s) h* E
4 c( _# C( l' R1 E* W6 B3 R) u+ {/ J ②//session.update(userInfo);! W& ~: p; Q1 D' a+ J9 Q
0 r4 n; r1 x3 O7 Z6 w; W. q
//session.update(userInfo2);
7 D1 _0 |5 F% S; L* X: ~
; G5 V5 R. ~8 `& ` //以下两句不会发送SQL,因为userInfo2不是持久化状态的实体
& ~* f7 T7 x$ z( h( r' `, u. C$ g6 x; X4 {/ X
③userInfo2.setName("RW5");3 T% t: {% s9 |4 b! F6 E
; l9 o9 B Q( _; c% e3 _ userInfo2.setSex("M");
q* m: t1 q% X. z7 Q) w5 s' E
//提交事务
" ?* _6 Y! }1 G
$ A ?- I" ]( [% J tx.commit();
& k4 y/ c/ q# ~# d* ?- O- c$ J5 U. V. |3 _7 N5 Y; ^
//关闭Hibernate Session
0 F) |' r+ b% ]2 L3 l3 h0 W0 Z' L8 z: u, ~
HibernateSessionFactory.closeSession();; y% _7 U% \0 T. Q4 X
% }; o {* D. s7 J }
! |' ?) N6 F0 A) S* s% A& m0 u% l* @5 M% x a4 l [7 W
针对该段代码将执行如下SQL语句:6 s: [0 P# H8 [3 A0 A* g
2 d7 U3 ~3 n6 F5 _ {4 X* ]8 HHibernate:
) _/ [8 J* j Y8 K- V) R
5 J/ Z h# U. W1 N5 r. a/* ①session.merge(userInfo2)的动作 */
h* A6 g9 f7 |9 J/ l7 D# _& n! o+ J: N5 V) F. Y) D/ n
select5 p" F1 k' _. {/ \1 `, m( A/ p
) P2 O' |1 M% P1 k, Y
userinfo0_.id as id0_0_,$ ]2 f5 `$ @% C0 D6 \( W
/ W9 ^# P$ S- a9 A& N( g userinfo0_.NAME as NAME0_0_,0 \) i1 p7 R, H& U
) |" H7 O5 D4 x2 N
userinfo0_.SEX as SEX0_0_,
& P8 G* d$ `; c5 d6 ]% ?1 n8 {: i* ]8 T/ H; R( W. ~: }" A
userinfo0_.roomid as roomid0_0_$ b1 s2 T) s" ^, E4 ^8 h
7 V+ M4 x! z7 X9 h; N# q from& U9 ^, y, W& M" `5 j
# j) _- V9 R% r, z8 Z2 D0 ?1 N userinfo userinfo0_8 ]7 _2 `) ^4 `$ e6 J% [
, a! x! X( M9 o) H; a
where. p7 y5 ?7 Q, B% ?
4 T3 z# G/ M0 ?0 M& h- j! w6 y userinfo0_.id=?% {/ ?1 g' C ?5 [
$ I; }$ S, _$ j: uHibernate:
$ G* y% ~3 b. C9 B, e% V; t$ w4 ~' _$ `9 C& P0 [
/* ①session.merge(userInfo2)的动作 */8 p- s9 y0 s( R e# o' N% E
2 o+ u4 _( J- v+ A- Rupdate1 N4 f6 K1 N" [! @
* K) C- a8 g0 h/ E0 @/ j4 ` userinfo' p$ r- F' f: m# ~: i7 S# G
8 i" v% y# R0 O- a0 s! d set/ p- v ^0 c$ ]3 z: @, [8 |1 X, I
" f6 }( @5 u9 R# X
NAME=?,
2 K: f; M( f7 C8 v3 B& X0 V: g. U# i; z, C7 O
SEX=?, t0 C7 c) ~& o5 t( r
+ W+ E1 j( r* M- w) h- `% c E: K roomid=?
7 x" u: C; f+ ?! R. K/ i
- N% T) i& g5 b& G: J: y where d, r/ |9 l- e; ]8 `6 \
- C2 }- Z5 l) c7 `+ a/ ?; d
id=?
7 B' g. Z6 r S& z# p
: y/ J2 e( N# l: qsession.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,那其结果只会执行最后一个session.merge()方法所发出的update语句。即使执行了session.merge()方法,UserInfo实体依然是脱管状态,因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。# b5 ~# _, g* S9 _6 s
9 H7 T' x% w; o4 H1 `8 r |
|