TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,也即该实体依然是脱管状。5 H. \* K& O$ H/ q9 k
session.merge ()方法对状态的变化& n) z9 k9 _$ o2 O! V4 J+ g8 M
( M5 z0 @, P8 z6 l. q* Z5 }. P( i% D public void run() {
/ r! A: t4 M- x4 ~+ i" e- d
2 d9 S2 H) m& z# k) _1 v, Y, D //创建UserInfo实例9 D) Z9 Z" ?0 W
; {) _8 A2 K- g* ?3 h/ X
UserInfo userInfo = new UserInfo();7 V1 W5 d' [; l" t8 }# x8 {
5 R. r! b, n! b9 V //使之成为脱管状态$ o# M4 b7 m4 \
( V5 `0 ?) m, w/ u% T2 h6 C1 L
userInfo.setId(11112);! W0 j4 E( C" {
: R$ U2 f |/ \
userInfo.setName("RW3");7 r+ `6 \ W. _
4 G3 ^: b4 |/ d5 q userInfo.setSex("M");
8 B5 I' S7 u- ]- p$ T6 O! L8 ?
//创建UserInfo实例2 F1 a5 h' ?- L6 @2 e
) o* Q8 }4 O3 j* F6 [# v UserInfo userInfo2 = new UserInfo();
9 n1 J( ? b+ `( j7 s; A( N$ r" X6 X) \- G( ?2 b8 u' B0 A
//使之成为脱管状态2 a! s" O% ]4 h* z9 d, q9 d& s3 @; K
% ?9 ~ O5 ], P, N% K: o. p$ b
userInfo2.setId(11112);( n1 R1 R+ W, f$ _! d
' |& A6 _+ U$ ~; R$ b* }0 l2 P: A userInfo2.setName("RW4");% _! T& h, U5 b- K5 p( q, v
! S. x0 b* X6 r+ b/ V: Q; V
userInfo2.setSex("F");( V' { S5 ?0 O: A% _
3 u% i) y0 i7 U) q3 b. O6 z" S+ o6 m
//启动Session
6 A, Q2 x6 S+ h
i. q# ^/ H5 F. v- V8 x Session session = hibernateSessionFactory.currentSession();
. `" p1 W: L9 e J. |/ J! N
- J9 l3 @4 G/ Q+ F1 W. A$ b( ] //启动事务/ b* t. D' Q: ^/ `
; Q. D. _ d. n- i& @* G8 { | Transaction tx = session.beginTransaction();
# n. s% {' e5 \6 N* k& X! ]1 N
% P; L8 x& a6 m' \4 ] //调用merge方法,此时UserInfo实体状态并没有被持久化2 e% F& V! Q! q0 v
' {/ @" p1 U4 i8 H3 I" Y5 B session.merge(userInfo);( c: I* V; l* j% h. P2 n
" B3 {' m5 Z3 Z P
//调用merge方法,此时UserInfo实体状态并没有被持久化6 S& e. f' p/ L
+ @7 r1 E8 r$ q7 T" G7 B
//但是数据库中的记录被更新了
* P$ ^( c* ^: ~* M1 Q: E
& `* [8 X$ ^: b: e ①session.merge(userInfo2);3 j) [% x0 ~0 e" R$ ~+ A
6 D) y5 i' o3 A; Q //merge方法与update方法的差别在于针对同样的操作update方法会报错
6 O9 E" M1 `' d- H, ~5 A& S
+ o0 _" k: F# u( t8 Q- S. ~" H/ P //原因在于update方法使得实体状态成为了持久化状态,而Session中不允许两个持久化实体有同样的持久化标识
" ~9 V p7 k5 q& I
" b4 K' M' ]+ q ②//session.update(userInfo);; l7 r I% l4 _& m
7 q2 x3 {0 S1 _/ Y4 s //session.update(userInfo2);% V" N% s( g* t' m2 ]" R
& D$ O- V7 [# A2 H4 J# B
//以下两句不会发送SQL,因为userInfo2不是持久化状态的实体+ [+ o( g x! k4 U7 ~4 Q4 o' b; V
* G/ f v' B3 v" h# I0 L% P s
③userInfo2.setName("RW5");* z5 N5 d. |/ i- t: l) Q" c
( p# z* V4 L" _) \5 U) [
userInfo2.setSex("M");
6 T8 f, B; a7 @( K0 b9 v7 Z* f% \0 z" A5 d# ^7 a: z/ p* V; r
//提交事务& H! }0 F/ x6 M; K
! C+ a5 p( [9 N/ P6 r: R' c o tx.commit();
" {% b. K2 F4 W+ V
+ b. G1 f& G. A* G5 l4 f" g //关闭Hibernate Session# K" g2 O8 f* F* G* y2 X: f
: e8 _/ f2 L. {4 Q3 C: U HibernateSessionFactory.closeSession();$ h, O, G% R9 {) N$ D: t
* Z, O. d$ Q6 ^. \ x }( p* f; S9 S+ F I; E+ e* b0 V
0 Y9 C& e/ @" d i
针对该段代码将执行如下SQL语句:
3 X! w4 o6 Y6 J9 n+ Y) S: d! q! x! }9 C+ R. J
Hibernate:7 g) E) U* `. l5 |+ f6 g- h: i- m
5 i% K! C4 _9 ?2 u0 @
/* ①session.merge(userInfo2)的动作 */7 B, k, r. ]5 @" H
4 k& E- A# b9 ^5 i/ \2 sselect
& }" p; {1 t i+ c7 s' I+ @2 G/ y! \' D# E( [
userinfo0_.id as id0_0_,% J1 ^3 [# N% D i: J
j+ ] d) n/ ?( m5 ~ userinfo0_.NAME as NAME0_0_,
& c. I+ g. X$ I$ h r& z0 w) m! h
userinfo0_.SEX as SEX0_0_,
, Q b1 T" M6 Q" ^$ }3 _+ u/ H
' `0 O+ K9 X: W# }- B userinfo0_.roomid as roomid0_0_
9 x3 C2 _- t. W* g- [, A( l. M" q: z b1 }6 k6 q# W! `
from$ U" e: U& z; k& E" l- ~! O! u
* G4 J" L( l9 {* e. ~
userinfo userinfo0_
2 K$ Y O1 U7 Q: B' L( k) w, k: q9 |' h) C# a+ v6 E
where
( U ]: h; b8 C4 R. K. q
! O0 W5 ^% F+ W5 c0 q4 y+ S userinfo0_.id=?
- X" ?( S5 b% a, X
u {* I% W& h3 k' WHibernate:
- ^7 ]7 i- |& i% S7 A/ m
- D4 b4 z/ L: V! k/* ①session.merge(userInfo2)的动作 */4 r( r: C" {$ S0 D/ R+ R4 `
! H' n: ^5 G+ O4 x# J! R8 Pupdate
9 G: f9 T" h W+ n0 w4 y' O
9 S7 {+ x% F+ l" @ userinfo$ w6 j9 L. H; A& v
9 i5 y4 F2 w. R8 [ set
5 t" ?- t" A) I7 m
& O1 e+ S* T; s9 F+ A3 O9 Q Y NAME=?,
1 L5 V; C7 g) L u9 R! r4 H2 P- y. G+ t. X" j! `6 H
SEX=?,1 l- ^, G! [0 f% S" x8 @5 U9 ?/ d
% M" ?+ k" b3 V2 M! b9 v) O
roomid=?
n1 t" a* m( w& Z _: N- _
- ~; g. U) J" Z9 O" _3 N where
% U* n6 [/ J, G4 F' G- C# T( k) r3 x& {0 G' C: I
id=?1 g0 N$ _" t& j& c. P2 T! w
7 p9 ?8 H- I6 H6 [& Ysession.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,那其结果只会执行最后一个session.merge()方法所发出的update语句。即使执行了session.merge()方法,UserInfo实体依然是脱管状态,因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。% ~7 M+ W3 {7 @7 l3 q; y# e
# s4 v8 I' Z9 m
|
|