TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
struts+hibernate+spring整合开发web应用是相当流行的,只需要简单的配置就能轻松的对数据库进行crud操作,下面就hibernate+spring的配置做一下剖析,一边与大家一起分享经验: 4 m2 U* l; a/ M
7 u1 p1 e9 [& R- O+ L- Z
1、 准备工作: " _$ W1 o+ M; @$ P1 b9 {
3 ^4 N* \2 ?: e8 P可以利用hibernate tools生成相关映射文件已经po对象、dao对象,dao也可以自己手动编写,无非就是实现crud,如果通过继承hibernate提供的HibernateDaoSupport,则可以更轻松的实现 , r, B1 x' [- M9 I, c
9 q% |$ d" Y( X3 h) M关键就在于配置文件,下面看一个样例app.xml: 8 ], [' T# u. D% ^6 O T9 b
' W5 U8 p5 L/ ?& F8 s<?xml version="1.0" encoding="utf-8"?> + _7 c: ]4 Z% N0 o/ W2 c" L
: |& \6 W& g/ H. F+ F<beans xmlns="http://www.springframework.org/schema/beans"
2 e# W7 q3 o' d# L" R0 B, D; z1 d4 Y7 S. R+ I. H7 E. D8 w
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 F# ~ n- E# g3 H( c( e2 C/ G y- F+ _+ q. V; L
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
5 Q8 v7 l- F- B
4 W; j4 g" {4 p1 Y* N2 }& E<!--配置数据源-->
0 N$ t; i5 c' q5 n" j6 E% d6 e r Y5 z! ?8 b* `% c& l
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
( n( t! a6 E% W3 @1 N9 d4 F0 P1 @$ Q4 d7 |! k$ R# Y P
<!-- 指定连接数据库的驱动 --> " P) ] h2 Z4 b; ^$ Q- f
& y7 x+ n, P; V1 G* g
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
( w- l4 t+ l- A) w/ A! b+ ]5 C* m) d) N: V7 H8 {4 Y
<!-- 指定连接数据库的URL -->
/ [+ S6 l# q9 q9 p m: y4 k
8 c0 B) ~& X; d; h <property name="jdbcUrl" value="jdbc:mysql://localhost/auction"/>
$ \4 G$ u$ Z( @ I$ y+ p. _& |
<!-- 指定连接数据库的用户名 --> ' P' f, f8 n$ N5 x m' x1 ?" X
+ b E0 s: u0 t( l* b+ n7 }4 M2 u0 x
<property name="user" value="root"/>
* v1 P0 {$ C$ Y1 n8 l
3 o- t" z$ f# U: @6 |; K; } <!-- 指定连接数据库的密码 --> , \: a/ w: Y+ G! Z- {) _5 R" c
8 d. p. N$ y" |4 y! ^' w <property name="password" value="root"/> 1 W4 l8 I* U* \& b8 f" q) d, T
8 D0 l; l: J$ J+ Y$ j) L <!-- 指定连接数据库连接池的最大连接数 --> + {* `: k9 L* s* W; ^6 B
/ d( I+ P2 b1 ?
<property name="maxPoolSize" value="20"/>
" P# a& {% _. K% |5 Z4 n2 S2 H5 i' K5 _ h* P! v/ d
<!-- 指定连接数据库连接池的最小连接数 --> 6 x6 k" g: `+ @( V# H" h0 O4 C7 F% \
7 w2 @6 z' N" A- a0 I <property name="minPoolSize" value="1"/>
/ F/ Z& W0 F& g- o, v. Y! I. m6 K1 M9 B% }
<!-- 指定连接数据库连接池的初始化连接数 --> : D* F4 X: c6 a: V8 c' s; t
0 o6 W2 P, o9 Q; a4 [( a: A
<property name="initialPoolSize" value="1"/>
$ t+ Z+ R$ Q; P$ \3 K9 t0 i
. m$ m+ A. X7 N, v- } <!-- 指定连接数据库连接池的连接的最大空闲时间 -->
q4 P' u$ L1 ~" p% @& r7 [7 q$ v7 o; f+ U$ J4 \" p# q2 v. w
<property name="maxIdleTime" value="20"/>
- d) C, p& u( X; Q6 G' ~& t
. O, z; x5 k6 o! |( m& B% ^& } </bean>
4 k% V) |6 q8 v$ t* ?
8 T+ N( A" P9 |
3 W J# {$ w0 g. K
2 p6 x: G- V9 T3 b! {) t' L/ A <!--配置数据库会话工厂-->
6 R% m1 s6 d- L8 W
, U6 U) c1 m+ Y5 K5 q S1 \ <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> & |. y2 e; L _ n j
' j0 G4 Z0 X x9 k1 q+ A
<property name="dataSource" ref="dataSource"/> 7 l- \4 J4 i; k' z7 J B
0 X# h; k/ L! e6 @
<property name="mappingResources"> # t& P6 s. G" e1 a
, N0 H4 N, M5 _) g7 ~2 X <list>
5 {$ V3 z3 Q. G, T% M2 D5 t# P) F- P/ s1 y; n3 O$ |# e$ [
<value>com/ouya/User.hbm.xml</value> ) x2 f& y4 A3 |7 E# V; J
' c0 G4 }8 m9 b </list> * G1 a* W2 m% {; L0 L A6 J/ ?
) v) f2 i) L$ Y. k
</property>
* _9 \$ U: b1 r* X/ E3 o9 O* C
5 O' Q' Z. h* \1 n# b( M! _7 i. S <property name="hibernateProperties">
/ i% C6 V5 Q/ }& x+ H1 y7 \( f
8 U1 j+ J$ ^; r0 K! Y3 @ <props> $ N, `, {- P5 ^' H
# W5 |4 L7 D, A/ h* ^% O
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 8 \9 ^5 N+ ]* E+ r' d8 T
8 U+ a9 [' [% m Z+ G
<prop key="hibernate.show_sql">true</prop> M" l8 m' ]+ i, q
" Z. h) ^, _0 i% d2 `
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop> 6 o- _9 K: K/ T
# @& E' ]4 }* D3 |6 a4 s9 i' C
</props> 8 N) o! v' A5 {+ L8 T3 }0 f! O) r
$ _# L7 V c4 j1 u/ ?! p) Y
</property>
4 z' G# U% r% |2 I1 h- r5 O0 O" ]! Q1 R" k
</bean> ' y) @6 u' ~ l9 H% p' ]
3 E: O4 w# I+ _! ^
6 U7 E# v( H1 ^- g6 q1 o
/ ]; B& F5 B7 u' H* V7 N<!--配置事务管理器-->
* I9 O3 K% p& ]: z( P$ l1 L( m5 D" b, w
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> ; t/ }9 h b! t* }% B# ~
( \4 J8 M0 k2 |1 E& H/ F <property name="sessionFactory"><ref local="sessionFactory"/></property> ) E- ~9 }$ r, r$ m: q! \) s7 |
8 G0 q$ N4 w+ T</bean>
& H2 I5 d% I% Q6 K7 |
( [/ p9 z/ Z! s0 x3 f <!—-配置Spring 事务管理器代理 -->
$ T0 ~, d7 [- ~! n9 q( l6 c% G- S5 a# j2 L) q9 f) w
<bean id="transactionProxyFactory" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> + y: m+ i/ j% `+ v8 L# [& R
" J/ L! V* @& |' P, `# l
<property name="transactionManager"> 0 E% [ v+ u/ o6 N q5 _/ J& C
' b( d* P1 u- b/ U3 z
<ref local="transactionManager"/>
r& Y [& m( C$ Y/ {" m$ O# B0 w9 k5 F' G; D
</property>
. K# I- \2 \, [1 t) |
$ b1 D0 x! `; C' B2 E% u2 _# g; { <property name="transactionAttributes"> ( G4 w- e G: B- t! @# \3 o
# o. l0 @9 n2 f; Z <props>
+ `& k5 \+ s+ t1 d# m) \" [7 T7 F4 B4 _$ I$ G' w! L' A
<prop key="save*">PROPAGATION_REQUIRED</prop> 5 J- L, A. e( `
A) j2 i; o n3 z' V4 ? <prop key="insert*">PROPAGATION_REQUIRED</prop> * F* t# n8 |6 \( l$ r
) ~- }+ c8 Q4 R0 [, S5 } <prop key="del*">PROPAGATION_REQUIRED</prop> % U/ {; H" B% E) k
; c4 d$ y1 T7 v& C$ ~% a
<prop key="add*">PROPAGATION_REQUIRED</prop>
|' o, O) f- F
$ I8 j" I) C# g2 F8 R <prop key="update*">PROPAGATION_REQUIRED</prop>
- @: i* f2 F% J4 }: p u( M. ~& A) {: c) p8 D
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> . ?$ n0 v. |* _1 d4 y
# ]$ y/ D6 j/ j4 i' S3 h
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop> % A4 k* K" `/ w# R7 X# x
# E: ]$ a0 H4 f$ G2 K0 K1 [
<prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>
9 u" z( \4 p( o% ?. A
- V, c- q2 |1 t <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
& P6 r7 w2 k' Z" G9 e6 p
# p% O& R+ H3 @ <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop> $ W/ `. \* q. T. \) i* Y; Z
9 ~* x0 C \. ]. @% `4 D6 M- S <prop key="count*">PROPAGATION_REQUIRED,readOnly</prop> & K6 J8 e$ T6 Y4 C3 N
! ^ a; p, U: R( }7 }) d) u$ D <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
( i2 C+ z- y: t1 s2 g" M
# C* b1 |4 T$ U1 [5 e/ k+ G </props>
: U% o2 p' j& ?) h: |1 |1 W/ f7 b6 I2 q9 d$ E) |' |" o; @
</property> " O# a) W) Q$ ]
) k" G/ `3 a0 K/ g7 J% v </bean>
p& P& ^: I( N% a7 P i$ }4 O7 v3 r% _
<!-- Hibernate模板 -->
2 u3 T' `! C- Q3 H$ `& f9 [6 J' y9 P. k+ F1 s; q J" P
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> ' N# H6 _8 U0 F. t5 o5 F
/ P- B7 t( S2 e) N+ w <property name="sessionFactory"> ! y6 z0 v8 n1 D$ c3 X$ U
0 L! b: A8 M0 F1 L8 W
<ref local="sessionFactory" /> " q! H* M7 G0 z6 Y7 n
) q. v; C K9 h9 S v' o: f, P
</property>
# ~" t/ a* ^2 {2 D
* W' S9 w. W0 M3 v( P</bean> ! s; k" O2 c. F+ Y g1 |5 [; E' v
) m( x6 _3 r* A$ Y: V9 _ <!--服务层对象-->
0 Q# Y6 H% ^8 \, |; a3 I. e$ K% h. f: y; a
<bean id="us" class="com.ouya.UserService">
7 ?! {3 t, j) v" b' O5 y1 a6 f$ S5 c, @5 t0 M3 a7 E4 s7 h+ G. h( w
<property name="userDao">
/ W3 b6 D1 r4 M" r3 p
# M: e" \# c& s/ C9 A+ [5 m, R% n: J <ref local="userDao"/> . T8 ]) i- m9 T
& i. ^$ \4 @( `' u
</property>
1 `5 q# i3 Y3 y* O
, ]9 w/ u; f6 W8 l2 G </bean> ( r* }' K0 L' n* n# m0 M
& |: I2 }% S8 {: a0 I+ N* s <!-- spring代理用户服务对象 -->
5 |6 b$ i8 ?2 {. V; n1 y3 e& m' F) `# I
<bean id="userService" parent="transactionProxyFactory"> ! |( O0 d: `% \. g. d
0 V( [" @$ G, N L<!-- 如果上面的服务层对象实现了接口,则此处必须设置proxyTargetClass为true,否则会报classcast异常 --> 0 ^ _' X' v7 L+ _" v
$ w8 }( n: o s6 r& Z% W
<!--<property name="proxyTargetClass" value="true"/>--> # m- o- t- ^" [
2 A6 q8 q. ` a6 a4 i' k <property name="target" ref="us"/>
. [5 W' L2 W& s. p$ Y3 _) \& E% w* }" O( H. o
</bean>
2 T7 \7 V% ^# h! u& N: j* W x- d1 M: m$ m* }2 V1 ~7 ?
<!-- 用户数据访问对象DATA ACCESS OBJECT --> $ e- C# T' [' \- y
% D" g4 L5 E5 F9 Q- G+ j
<bean id="userDao" class="com.ouya.UserDAO"> ( y5 q( Q0 W) t2 ^# v2 [$ t* ^
2 a9 g' \: }2 x" j% U- U <property name="hibernateTemplate" ref="hibernateTemplate"/>
: Y; t' W p, C8 p N9 }, A5 O6 c
</bean> # G' x+ q* n% T- ~9 A$ H2 w
" D, M/ C/ J+ a# }' p6 f </beans>
- ]5 z6 s) M( ]3 [6 ]$ i+ s# z
4 t( P' \: ]2 G3 g- k可以看到配置文件的步骤:
Y; W$ z$ a9 j) C4 b' {
. c% o5 Y3 H U6 y2 @" k1 x1、 配置数据源
: C" i5 j& \$ l8 x j* X, d8 |4 i& i. k6 G( B0 B3 I. C* @
2、 配置会话工厂(依赖注入上面的数据源,还要注入hbm映射文件[注意正确的位置]、hibernate属性文件)
$ e8 R {/ k! P, }2 q: ?& b: {/ g
' g& |" g! p2 M: O3、 配置事务管理器(依赖注入上面的会话工厂)
! g& f- d, @) u5 @ o/ g/ ^9 [; [
; W! k+ V9 A' K# e, A7 d2 f3 M* l4、 Spring中声明事务管理器(根据需要又可分为几种,但都要依赖注入上面的事务管理器,此外还需要配置transationAttributes) 8 V8 f# v4 _* a. ?
& b3 u$ J0 y- x" M" X/ K1 L# ?
后面的一些普通的bean配置就不用说了
* V1 M" C$ c. O8 C/ o5 v6 L% l- q% u8 e
上面的例子中使用的声明事务管理器是:TransactionProxyFactoryBean,这样的话我们就需要在后面配置目标bean,比如上面的例子中我们的原服务对象是id为us的UserService(没有实现接口),所以我们为他配置了id为userService的代理对象(目标bean),程序中使用时只能通过使用代理对象才能实现数据库操作功能(代理对象的父类是上面声明的事务管理器,一边我们使用的时候开启事务),如果直接使用服务对象就无法开启事务 0 [9 i( L5 K6 D. G: ]
) ]1 q1 w+ s! i9 s: O
程序中调用:UserService us = (UserService) app.getBean("userService"); ( l( X! B( i3 @- l6 m8 K2 ] {
- Y3 w3 n _- n# b: g6 Z注:userService就是上面配置的代理对象的id,而不是原服务对象的id 7 w' S3 D& ~6 O, x+ u- R; N4 G
. i4 L& x2 V8 H4 Q, ~7 X! y4 G: B: x) x3 s6 D) X5 B" G( Z
# J5 {0 ?* L( E6 x5 _但是如果我们想通过原服务对象的id来使用对象,则我们需要使用代理事务管理器BeanNameAutoProxyCreator(根据beanname自动代理),上面的配置文件需要做改动,做两件事(当然先要删除原来配置的TransactionProxyFactoryBean,不然就混乱了,可能会报错的): % b$ h$ O4 j- h1 j. _
! C2 l* J3 c* c4 u$ B1、 增加一个事务拦截器
* J$ z: U' Z/ w4 e; i% T- V9 e1 ]* P2 E
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">2 v/ m6 L; m8 Q$ Q6 ^# ^/ d3 F
& b0 b Z* D8 C( Y o! |1 z, s
<property name="transactionManager">
) b; V/ U( I" o8 d
) Q" _# e/ G5 z5 F+ p$ \ [$ e <ref local="transactionManager"/> 6 W5 f' y- R- Z" X' R
+ G9 z8 v, P U </property>
) D' O; J: Q: d6 k+ R6 E5 b1 ]
/ _3 _# g; e: N <property name="transactionAttributes">
3 f0 A8 }! X' _! |, _9 J
" B3 N7 C; P3 e4 ?% h x <props>
2 h0 j$ L% ]' m- r$ G
9 B! f2 X5 U6 |8 M: D* i: v <prop key="save*">PROPAGATION_REQUIRED</prop> ! h: |7 z, W2 ]$ v% t
$ {' s Q+ T% F( G; l' ?
<prop key="insert*">PROPAGATION_REQUIRED</prop>
0 C; H' I2 g5 w, P! R. H2 R
8 ~! R4 z) q) |3 w1 | <prop key="del*">PROPAGATION_REQUIRED</prop>
7 ?' b- x9 X. g- s( D' p: [% G! C0 i6 S* J* A. h
<prop key="add*">PROPAGATION_REQUIRED</prop> ; X: n" r, k: j8 G4 j3 Y
! C9 q2 e+ u1 p- ?* N' C/ Z <prop key="update*">PROPAGATION_REQUIRED</prop>
) B/ P' s# i* a1 D& C6 @7 \
/ V6 F' b$ P8 y2 |" p0 }# _ <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> ' X" [0 i) L3 P$ t& D3 n
3 r7 I1 N- F" q; R% ~6 r, o Y
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop> & `5 H" @ @5 x8 f- s% B
$ q& [% q- t3 Z. O
<prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>
+ R% j' v M8 c+ [; q1 R2 J
/ Q2 J( s8 M6 ?( D* V7 {8 L1 N5 E/ d <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop> 5 b) q) \; ~' d" t: n0 [
3 V: ^: X$ G. {! Y <prop key="list*">PROPAGATION_REQUIRED,readOnly</prop> 1 ]) |5 P. n6 h/ m9 ] g$ z
5 J4 |" r5 ^% P( R6 ^
<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop> 0 T5 y4 _( O0 p
* O5 l! v; N; @' D$ ~4 t% x) P
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
: h* I, z8 f9 \# c1 L, c4 c: v- p) W# {. H$ A; r, p
</props> ) i1 a+ a; B* j6 I+ @# V. D
. V' Q( n! O& R" f o) {7 ?: N
</property>
4 h$ P1 b, k$ k! v! z# R0 v% s6 x8 [1 z$ {0 n+ _* w3 L7 }
</bean>
% F+ ?" C0 g" N/ j$ j" p. ^+ ^9 J+ A* N
$ y* G. K6 e, F, `3 j# e s' Q8 H% @# d% p0 R) S( s
|
|