TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,也即该实体依然是脱管状。- B% o1 z1 k4 m8 k( X& a
session.merge ()方法对状态的变化9 q; P, d* {3 n! m
! z3 Y4 v T0 z5 |4 X- A& l% R' d public void run() {
( L% W! K( N" n$ a# g0 f. l) z( D( S5 G- v1 ?
//创建UserInfo实例
7 e7 f! O9 ?: y2 X3 r1 Q3 b7 y: i- Q. m, n
UserInfo userInfo = new UserInfo();
3 u; ]2 i( ]. A* `' B: W/ F
/ N4 C% T# b6 D# L) I //使之成为脱管状态. `# ?$ f- A' Q" u$ m
! Y c/ j1 ~: ?1 c6 m9 |1 M
userInfo.setId(11112);
7 H/ o- u# P) B& N( @" v. j1 c
1 f. f y/ E/ I8 I2 ? userInfo.setName("RW3");
0 M* K" S! p J& q. q% L& q
- R& {# p/ @4 v* D7 U* m$ n6 ? userInfo.setSex("M");5 G1 w0 r$ L. E
$ l: N1 ]1 q+ q, V- T/ P //创建UserInfo实例
) ?4 y! ]$ x. E0 I; ^9 O: y
1 z5 J) A& l8 m UserInfo userInfo2 = new UserInfo();9 a* P9 z8 f- _+ }
- B/ P2 p% W" U; S- a! V' I+ | //使之成为脱管状态
1 H: g1 F; W, @/ o+ @1 ]; q" ?" z; J8 W7 k8 h* x K
userInfo2.setId(11112);
" L. |6 I+ I3 B; ]+ b& }- l9 L
# k0 }4 c: Q- u% z userInfo2.setName("RW4");6 I+ z/ G5 y9 e# M. v
7 j: c8 n: i0 Z! H2 v
userInfo2.setSex("F");
$ n8 i. X" j+ o# W5 [- g6 P% {) m6 k6 k5 j# M- R0 I7 Q
//启动Session
: W1 F5 O3 L4 K* i8 B8 V- y- S. y
" `$ L8 r9 }( v& w1 T8 R1 N Session session = hibernateSessionFactory.currentSession();, O/ @ G1 `+ `1 }. B
' F* {& \+ u4 R3 l1 [+ L" v
//启动事务2 @, n' s g6 r8 u( m9 ^
. I& ^" v3 {% Q: w Transaction tx = session.beginTransaction();# a* f* U$ ]/ g
U% h X) Z; ?, u
//调用merge方法,此时UserInfo实体状态并没有被持久化3 d* ?, M( t) I3 \/ V6 D; U2 I
# D0 R/ v8 |% H; M. N2 Q
session.merge(userInfo);
9 w4 R" Z9 b( e% _) Q+ H3 r; r/ P: J. T, {$ R1 N' t0 ^$ t* q$ M
//调用merge方法,此时UserInfo实体状态并没有被持久化& }8 W8 W0 x/ K# s4 b
6 R0 V) Z- S. Q //但是数据库中的记录被更新了
# {7 o# K, p" R1 q/ ^$ Y. P2 X& K- s" [
①session.merge(userInfo2);9 t, U; L. X* v
7 X2 V6 |' g; d# o* O7 C9 v" [
//merge方法与update方法的差别在于针对同样的操作update方法会报错
1 Y8 Y% z: q# V) x y# F- D& E N$ {, w& S" E
//原因在于update方法使得实体状态成为了持久化状态,而Session中不允许两个持久化实体有同样的持久化标识* q r) l- k. [, |! u
* l5 P" i8 Q+ H8 r$ K5 Q/ p* A; `
②//session.update(userInfo); V4 A! [4 {$ d G- c4 G
; z& N) ^( N& m6 J7 b
//session.update(userInfo2);
5 [, @& |. q2 j8 R: S8 Z% L2 L, J( o; u$ B, c- r: B/ @ h) y! L( s( }6 B
//以下两句不会发送SQL,因为userInfo2不是持久化状态的实体
0 ~7 G# n+ M( u, `# t# P
3 b8 O' {+ N/ \+ U) s0 ~# `! t$ b ③userInfo2.setName("RW5");
* E9 [4 M" B1 c9 Y- y2 K- h# ~5 ]" I- e% k7 P. O; }. D/ i
userInfo2.setSex("M");
+ t+ y: q H/ N
4 t% S2 L: v9 s! t; e0 l7 x //提交事务2 q" \6 f- B2 W8 L
1 z! a% u: x4 n+ @% [* } tx.commit();
+ W( l! l( X9 g' j* R- f7 ^) @! b9 c# r6 p' ?
//关闭Hibernate Session- J% u& A% H% f8 T/ `. X
& G# B2 x% U( I: m; j% \
HibernateSessionFactory.closeSession();
* F8 {5 G9 S3 {0 [& }7 c- B& N' D$ }* i- Y# T. | P+ A
}
. j$ C# H+ `5 k% G; j( w
' S$ B! \: `4 p E针对该段代码将执行如下SQL语句:& Z% m# w0 Z( U& h
/ \& J4 }! o2 u$ H6 e H3 n6 tHibernate:3 \* p, Q' B3 m
! n8 ^0 h, P7 g8 R9 k
/* ①session.merge(userInfo2)的动作 */% ?0 k+ o$ V/ g7 l8 }: K) a
- y9 M3 N, D) u2 {3 qselect0 L, U" O" c8 _
0 @4 T2 P8 P1 s/ z9 q userinfo0_.id as id0_0_,
7 z0 C3 ?( h' V1 T f" }0 G1 i; O2 U7 v9 d |
userinfo0_.NAME as NAME0_0_,; n1 Q0 [9 ]0 p% j( x W
) \# V- F4 i( X8 @ n0 T: O
userinfo0_.SEX as SEX0_0_," q$ S' J) A* a$ H, ?" C$ R
9 U3 r$ \4 p# Y- {( @. B! M0 ? userinfo0_.roomid as roomid0_0_( @. ]0 C6 t4 I% }3 f
/ Y3 Y# A" }& p! h' y" B& T" Y
from
9 S4 q& F. F3 q7 W
! I5 w% Z; c' l1 G userinfo userinfo0_
. |5 n4 U, p8 y* r' f! Z+ C# A2 e& y0 }$ O; Y1 H
where
5 p4 I; H S9 o+ @% l$ l& U" i7 X1 j' p" G
userinfo0_.id=?! N" S' r- R$ j1 O8 b: o* d
Y4 g! u; a$ @( \. c; t$ K5 |& d
Hibernate:! f+ U" r; f! N4 T
$ c3 ^# `8 v5 t( ~1 f' s9 V
/* ①session.merge(userInfo2)的动作 */& l/ L5 X7 G$ ^6 {% G( }3 ]
7 }2 c4 |% R6 |; Y7 t$ v* R0 [. m6 j
update
2 V& y* d% t. P! H) i9 y/ x6 |! K3 l% @+ C
userinfo
: z/ O. r) x8 r- b* M/ N
+ J2 z+ o- V; ` set1 r9 x F0 \; {& E
" X2 U2 \( K- v9 |' u* C5 Z0 B
NAME=?,* @! a" }0 A9 u# `- @8 P
- V+ ?: V. }0 F2 x6 J
SEX=?,
, z% Z$ N" c- g: }6 I
- ?% |% U' ?9 r) P roomid=?
! ?% Q+ h7 ?/ h q! |3 }& E( h1 E& \8 i
where
. [- ~- i4 f$ o7 I, M% d& @7 y
" j6 |7 r4 [9 C( U. _5 o* F id=?
% i9 f& K" m( J& o: j5 G0 a; u' }9 M8 E; M6 Y% }
session.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,那其结果只会执行最后一个session.merge()方法所发出的update语句。即使执行了session.merge()方法,UserInfo实体依然是脱管状态,因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。
n. i" j# M1 | }
$ Q }0 _6 f( L I |
|