|
通常建議采用聲明式事務(wù)管理。聲明式事務(wù)管理的優(yōu)勢(shì)非常明顯:代碼中無(wú)需關(guān)于關(guān)注事務(wù)邏輯,讓Spring聲明式事務(wù)管理負(fù)責(zé)事務(wù)邏輯,聲明式事務(wù)管理無(wú)需與具體的事務(wù)邏輯耦合,可以方便地在不同事務(wù)邏輯之間切換。 一. 利用TransactionProxyFactoryBean生成事務(wù)代理 <?xml version="1.0" encoding="gb2312"?> <!-- Spring配置文件的文件頭,包含DTD等信息--> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd"> <beans> <!--定義數(shù)據(jù)源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 定義數(shù)據(jù)庫(kù)驅(qū)動(dòng)--> <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property> <!-- 定義數(shù)據(jù)庫(kù)url--> <property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property> <!-- 定義數(shù)據(jù)庫(kù)用戶名--> <property name="username"><value>root</value></property> <!-- 定義數(shù)據(jù)庫(kù)密碼--> <property name="password"><value>32147</value></property> </bean> <!--定義一個(gè)hibernate的SessionFactory--> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 定義SessionFactory必須注入DataSource--> <property name="dataSource"><ref local="dataSource"/></property> <property name="mappingResources"> <list> <!--以下用來(lái)列出所有的PO映射文件--> <value>Person.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <!--此處用來(lái)定義hibernate的SessionFactory的屬性: 不同數(shù)據(jù)庫(kù)連接,啟動(dòng)時(shí)選擇create,update,create-drop--> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> <!-- 定義事務(wù)管理器,使用適用于Hibernte的事務(wù)管理器--> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <!-- HibernateTransactionManager bean需要依賴注入一個(gè)SessionFactory bean的引用--> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <!--定義DAO Bean , 作為事務(wù)代理的目標(biāo)--> <bean id="personDaoTarget" class="lee.PersonDaoHibernate"> <!-- 為DAO bean注入SessionFactory引用--> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <!-- 定義DAO bean的事務(wù)代理--> <bean id="personDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 為事務(wù)代理bean注入事務(wù)管理器--> <property name="transactionManager"><ref bean="transactionManager"/></property> <!-- 設(shè)置事務(wù)屬性--> <property name="transactionAttributes"> <props> <!-- 所有以find開(kāi)頭的方法,采用required的事務(wù)策略,并且只讀--> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <!-- 其他方法,采用required的事務(wù)策略 -> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> <!-- 為事務(wù)代理bean設(shè)置目標(biāo)bean --> <property name="target"> <ref local="personDaoTarget"/> </property> </bean> </beans>在上面的配置文件中,personDao需要配置兩個(gè)部分,一個(gè)是personDao的目標(biāo)bean,該目標(biāo)bean是實(shí)際DAO bean,以實(shí)際的DAO bean為目標(biāo),建立事務(wù)代理。一個(gè)組件,需要來(lái)個(gè)bean組成,一個(gè)目標(biāo)bean,一個(gè)事務(wù)代理。 <!-- 定義DAO bean的事務(wù)代理--> <bean id="personDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 為事務(wù)代理bean注入事務(wù)管理器--> <property name="transactionManager"><ref bean="transactionManager"/></property> <!-- 設(shè)置事務(wù)屬性--> <property name="transactionAttributes"> <props> <!-- 所有以find開(kāi)頭的方法,采用required的事務(wù)策略,并且只讀--> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <!-- 其他方法,采用required的事務(wù)策略 -> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> <!-- 為事務(wù)代理bean設(shè)置目標(biāo)bean --> <property name="target"> <!-- 采用嵌套bean配置目標(biāo)bean--> <bean class="lee.PersonDaoHibernate"> <!-- 為DAO bean注入SessionFactory引用--> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> </property> </bean>==================================================================================== 使用HibernateTemplate的方法進(jìn)行CRUD操作,其中查詢操作通常可分為兩種,一種為固定條件查詢,另一種為動(dòng)態(tài)多條件查詢(如查詢界面 的實(shí)現(xiàn)),固定條件查詢可以很方便地通過(guò)createQuery,find()等方法實(shí)現(xiàn),但是我在動(dòng)態(tài)條件查詢的實(shí)現(xiàn)過(guò)程中,hibernate3.0 可以實(shí)現(xiàn)英文的條件查詢,而中文條件則會(huì)出現(xiàn)亂碼?,F(xiàn)將具體的過(guò)程描述如下: 1.固定條件查詢 可以使用常規(guī)的方法,如getHibernateTemplate().find(),getHibernateTemplate().createQuery()等 2.動(dòng)態(tài)多條件查詢 由于查詢條件的不確定性,我曾嘗試用拼參數(shù)的方法將拼好的sql語(yǔ)句傳入find(qlStr),但是查詢時(shí)hibernate會(huì)將中文的條件報(bào)為亂碼。不過(guò)如果條件全部是英文參數(shù)的話拼sql是可以的。亂碼報(bào)錯(cuò)如下: 說(shuō)明:由于find(String arg0,Object[] arg1)采用數(shù)組參數(shù)的方式可以使用中文條件查詢,因此可以確定不是我的編碼問(wèn)題。而是Hibernate3.0的find(sqlStr)方法本身的問(wèn)題。 為此只能換成另一種實(shí)現(xiàn)途徑,如下: 實(shí)現(xiàn)途徑:
②
以上方法可以實(shí)現(xiàn)動(dòng)態(tài)中文條件查詢,在有的書(shū)中看到并不推薦用find()方法,find()只提供一些簡(jiǎn)單的HQL查詢,不具有動(dòng)態(tài)綁定參數(shù)的功 能,在將來(lái)的hibernate新版本中,有可能會(huì)淘汰find()方法,而Query接口才是真正的HQL查詢接口,提供更為豐富的功能。基于此,可能 對(duì)于一個(gè)將被淘汰的方法find()不支持中文也就不足為奇了。^_^畢竟人家重心轉(zhuǎn)移了。而且find()中拼sql字符串的方式雖然是實(shí)現(xiàn)查詢的常用 手段,實(shí)現(xiàn)起來(lái)也比較方便,但是不利于hibernate更好地利用緩存,而采用Query接口可以更好地利用緩存,提高程序執(zhí)行效率。 |
|
|