TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,也即该实体依然是脱管状。. 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% ^# ^
|
|