淺談SpringHibernate整合_第1頁
淺談SpringHibernate整合_第2頁
淺談SpringHibernate整合_第3頁
淺談SpringHibernate整合_第4頁
淺談SpringHibernate整合_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、 Spring+Hibernate整合Spring是一個輕量級的bean容器,它為業(yè)務對象(business objects)、DAO對象和資源對象(如:JDBC數(shù)據(jù)源或者Hibernate SessionFactorie等)提供了IoC類型的裝配能力。Spring通過使用一個xml格式的配置文件,為開發(fā)者提供了一種通過定制屬性文件來手動管理單例對象或工廠對象的可選擇性。由于Spring將非侵入性做為一個重要的目標,因此由Spring配置管理的bean均不需要依賴Spring自身的接口和類,就可以通過它們的bean屬性完成配置。從而可以被應用到任何環(huán)境中,無論你開發(fā)的是一個J2EE的web應用

2、還是一個桌面應用甚至只是一個applet都可以。在使用Hibernate的應用中,Spring對DAO對象通常的事務管理機制應該特別引起關注。它的目的就是分離數(shù)據(jù)訪問和事務處理,使事務性業(yè)務對象不與任何特殊的數(shù)據(jù)訪問或事務策略耦合在一起,從而不影響業(yè)務對象的可復用性。這種劃分既可以經(jīng)由事務模板(TransactionTemplate)用在java代碼中編程的方式實現(xiàn),也可以經(jīng)由AOP的事務攔截器(一般用TransactionProxyFactoryBean)用在配置文件中聲明的方式實現(xiàn)。無論是本地的Hibernate / JDBC事務,還是JTA事務都支持對象外的事務策略,這對于本地的無狀態(tài)會

3、話Bean是一個非常有用的選擇。 Spring的HibernateTemplate類提供了一個簡單的方式實現(xiàn)了Hibernate-based DAO對象,而不必關心如何獲得Hibernate的Session實例,也不必關心多方參與的事務處理。無需使用try-catch塊,也無需進行事務檢查。一個簡單的Hibernate訪問方法就完全解決了這些麻煩! 無論是在多個DAO接口還是在多方事務的情況下,Spring使得多種DAO對象無縫地協(xié)同工作。例如:某些DAO對象可能是基于plain JDBC的實現(xiàn),更適合于經(jīng)由Spring的JdbcTemplate來避免手動的異常處理。 你可以單獨地使用許多Sp

4、ring特性,因為Spring的所有對象都是設計成可復用的JavaBean的集合。使用其他的Spring特性時,應用配置概念是一個附加的特性,并不是一個必須的特性。無論如何,當你要決定去構建一個象 Spring這樣的在的基礎架構的時候并沒有什么圍上的限制。1. 介紹: 資源管理 典型的業(yè)務應用系統(tǒng)常常由于重復的資源管理代碼而導致混亂。許多項目試著用自己的方法來解決這個問題,有時為此要付出失敗的代價,Spring針對適當?shù)馁Y源管理提倡了一種引人注目的簡單方法:即經(jīng)由模板來倒置控制(Inversion of control),例如:基礎類使用回調(diào)接口,或者應用AOP攔截器。其基礎核心是適當?shù)馁Y源處

5、理和將特殊的API異常轉換為一個unchecked的基礎異常。 Spring引入了一個DAO異常層用于任何數(shù)據(jù)訪問策略。Spring框架對于直接的JDBC或JdbcTemplate類,都會將Connection異常、SQLException異常轉換為適當?shù)腄ataAccessException異常,包括對特殊數(shù)據(jù)庫的SQL錯誤轉換為有意義的異常。經(jīng)由不同的事務管理對象,Spring支持JTA和JDBC事務。Spring 也提供對Hibernate的支持,它的這種支持由類似于JdbcTemplate的HibernateTemplate類、HibernateInterceptor類,還有Hiber

6、nate事務管理類組成。 Spring框架最主要的目的是使系統(tǒng)層次分明,即將數(shù)據(jù)訪問和事務處理同應用對象分離開來。所有的業(yè)務對象都不再依賴數(shù)據(jù)訪問或者事務策略。不再有硬編碼的資源查找代碼,不再有難以替換的單例對象,也不再需要定制服務注冊。 所有的單獨的數(shù)據(jù)訪問特性均無需依賴于Spring而單獨使用,無需讓Spring知道,同時也可以通過Spring的應用配置來進行裝配(提供基于XML的配置和對普通JavaBean實例的交叉引用)。在一個典型的Spring應用中,大部分重要的對象都是普通的JavaBean:數(shù)據(jù)訪問模板對象(data access templates)、數(shù)據(jù)訪問對象(使用數(shù)據(jù)訪問

7、模板對象的對象)、事務管理對象與業(yè)務對象(使用數(shù)據(jù)訪問對象和事務對象的對象),web表示分解對象、web控制對象(使用業(yè)務對象的對象)等等。2. 應用配置中的資源定義 為了避免應用對象將查找資源的代碼進行硬編碼,Spring允許在應用配置中將一個如JDBC DataSource或者Hibernate SessionFactory定義為一個Bean。應用對象如果需要訪問資源只需要通過Bean引用(DAO定義在下一部分說明)接受先前定義的實例的引用。以下的容引用自一個應用配置定義,顯示了如何建立一個JDBC DataSource和一個Hibernate的SessionFactory:<bea

8、ns><bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"><property name="jndiName"><value>jdbc/myds</value></property></bean><bean id="mySessionFactory" class="org.springframework.orm.hibe

9、rnate.LocalSessionFactoryBean"><property name="mappingResources"><list><value>product.hbm.xml</value></list></property><property name="hibernateProperties"><props><prop key="hibernate.dialect">net.sf.hibernat

10、e.dialect.MySQLDialect</prop></props></property><property name="dataSource"><ref bean="myDataSource"/></property></bean>.</beans> 注意選擇是用JNDI來定位數(shù)據(jù)源還是從一個象Jakarta Commons DBCP BasicDataSource這樣的本地定義取得一個數(shù)據(jù)源,只需要改變配置文件就行了:<bean id=&quo

11、t;myDataSource" class="org.apache mons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName"><value>org.hsqldb.jdbcDriver</value></property><property name="url"><value>jdbc:hsqldb:hsql:/localho

12、st:9001</value></property><property name="username"><value>sa</value></property><property name="password"><value></value></property></bean> 你也可以使用一個JNDI查找SessionFactory,但是通常對于E環(huán)境之外的應用來說并不是需要的。3. 倒置控制(Inversion of C

13、ontrol): 模板和回調(diào) 模板的基本編程方法就如同任何定制的數(shù)據(jù)訪問對象或者業(yè)務的對象的方法一樣:僅僅提供一個Hibernate的 SessionFactory。雖然最好是從Spring的應用配置中經(jīng)由一個簡單setSessionFactory bean的屬性設置使用Bean引用來獲得它,但隨后你可以從任何地方獲得它。隨后的引用片段包括一段在Spring應用配置中對DAO定義的配置,其中引用了在其前面定義的SessionFactory,和一段DAO方法的實現(xiàn)的例子。<beans><bean id="myProductDao" class="p

14、roduct.ProductDaoImpl"><property name="sessionFactory"><ref bean="mySessionFactory"/></property></bean></beans>java代碼:public class ProductDaoImpl implements ProductDao private SessionFactory sessionFactory;public void setSessionFactory(Sessio

15、nFactory sessionFactory) this.sessionFactory = sessionFactory;public List loadProductsByCategory(final String category) HibernateTemplate hibernateTemplate =new HibernateTemplate(this.sessionFactory);return (List) hibernateTemplate.execute(new HibernateCallback() public Object doInHibernate(Session

16、session) throwsHibernateException List result = session.find("from test.Product product where product.category=?",category, Hibernate.STRING);/ do some further stuff with the result listreturn result;);通常對于以上的java代碼,一般都會繼承HibernateDaoSupport類,而在該類中已經(jīng)定義了SessionFactory,所以無需再重復定義,而直接定義DAO實現(xiàn)方法

17、就行了。即:public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao public List loadProductsByCategory(final String category) HibernateTemplate hibernateTemplate =new HibernateTemplate(this.sessionFactory);return (List) hibernateTemplate.execute(new HibernateCallback() public Object

18、doInHibernate(Session session) throwsHibernateException List result = session.find("from test.Product product where product.category=?",category, Hibernate.STRING);/ do some further stuff with the result listreturn result;);在任何Hibernate數(shù)據(jù)訪問中都可以進行事務回滾。在任何情況下都由HibernateTemplate來管理Session的開閉和

19、自動的多方事務。模板實例是線程安全和可重用的,因此它們可以做為其他類的變量。 對于簡單的單步動作,象find、load、saveOrUpdate或delete的調(diào)用,HibernateTemplate提供更為便利的選擇以代替象一行的回調(diào)的執(zhí)行。此外,Spring 提供了一個方便的基本類,就是HibernateDaoSupport類,它提供了setSessionFactory方法來接受一個 SessionFactory,同時提供了getSessionFactory和getHibernateTemplate方法供其繼承類使用。將這些結合起來,允許對于典型的需求給出了非常簡單的DAO實現(xiàn):publi

20、c class ProductDaoImpl extends HibernateDaoSupport implements ProductDaopublic List loadProductsByCategory(String category) return getHibernateTemplate().find("from test.Product product where product.category=?",category,Hibernate.STRING); 4. 應用一個AOP攔截器代替一個模板 除使用HibernateTemplate之外的另一個選擇就是

21、使用Spring的AOP HibernateInterceptor。用直接在一個委托的try/catch塊中編寫Hibernate代碼,配合在應用配置中針對的攔截器進行來代替執(zhí)行回調(diào)。下面的片段顯示了一個Spring應用配置中的DAO,interceptor和proxy的各自的定義,同時給出了一個DAO方法實現(xiàn)的例子:<beans><bean id="myHibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor"><

22、property name="sessionFactory"><ref bean="mySessionFactory"/></property></bean><bean id="myProductDaoTarget" class="product.ProductDaoImpl"><property name="sessionFactory"><ref bean="mySessionFactory"/>

23、;</property></bean><bean id="myProductDao" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="proxyInterfaces"><value>product.ProductDao</value></property><property name="interceptorNames">

24、;<list><value>myHibernateInterceptor</value><value>myProductDaoTarget</value></list></property></bean></beans>java代碼:public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao public List loadProductsByCategory(final String cat

25、egory)throws MyException Session session = SessionFactoryUtils.getSession(getSessionFactory(),false);TryList result = session.find("from test.Product product where product.category=?",category, Hibernate.STRING);if (result = null)throw new MyException("invalid search result");ret

26、urn result;catch (HibernateException ex)throw SessionFactoryUtils.convertHibernateAccessException(ex); 這個方法將只在有一個與它配合的HibernateInterceptor時才能正常工作,HibernateInterceptor為它負責在方法調(diào)用前線程綁定Session的開啟和方法調(diào)用后的關閉。getSession方法調(diào)用中的"false"標志是要確認Session必須是已經(jīng)存在的,如果沒有發(fā)現(xiàn)任何一個Session,SessionFactoryUtils將會為其創(chuàng)建一個

27、。如果已經(jīng)有一個Session句柄綁定在本線程上,比如是由一個HibernateTransactionManager事務綁定的,在任何情況下SessionFactoryUtils會自動接入這個Session。HibernateTemplate在底層也使用SessionFactoryUtils,與以上說的方式基本是一樣的。 HibernateInterceptor的主要益處是它允許在數(shù)據(jù)訪問代碼中拋出checked application exception,而HibernateTemplate由于受限于回調(diào)只能在其中拋出unchecked exceptions。注意到這點我們可以推遲各自的檢驗

28、,同時在回調(diào)后拋出應用異常。攔截方式的主要缺點是它需要在配置中進行特殊的配置。 HibernateTemplate在大多數(shù)情況下都是一種簡單好用的方法。5. 程序事務劃分 在這種底層的數(shù)據(jù)訪問服務之上,事務處理可以在更高的應用層中形成一些操作。這里除了需要一個Spring的PlatformTransactionManager對象外,對于周圍運行的業(yè)務對象也沒有任何限制。同樣的,其后你可以從任何地方獲得它們,但是經(jīng)由Bean引用的方式通過setTransactionManage方法獲得更為適合,象 productDAO要經(jīng)由一個setProductDao方法獲得一樣。下面的引用片段顯示了在一個S

29、pring應用配置中的事務管理對象和業(yè)務對象的定義,并且還提供了一個業(yè)務方法實現(xiàn)的例子:<beans><bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"><property name="sessionFactory"><ref bean="mySessionFactory"/></property><

30、/bean><bean id="myProductService" class="product.ProductServiceImpl"><property name="transactionManager"><ref bean="myTransactionManager"/></property><property name="productDao"><ref bean="myProductDao"/&

31、gt;</property></bean></beans>java代碼:public class ProductServiceImpl implements ProductServiceprivate PlatformTransactionManager transactionManager;private ProductDao productDao;public void setTransactionManager(PlatformTransactionManager transactionManager) this.transactionManager

32、= transactionManager;public void setProductDao(ProductDao productDao) ductDao = productDao;public void increasePriceOfAllProductsInCategory(final Stringcategory) TransactionTemplate transactionTemplate =new TransactionTemplate(this.transactionManager);transactionTemplate.setPropagationBehavi

33、or(TransactionDefinition.PROPAGATION_REQUIRED);transactionTemplate.execute(new TransactionCallbackWithoutResult() public void doInTransactionWithoutResult(TransactionStatus status) List productsToChange = productDAO.loadProductsByCategory(category););6. 聲明性事務劃分 我們還可以選擇使用Spring的AOP TransactionInterce

34、ptor通過在應用配置中定義攔截器配置來代替事務劃分代碼的事務處理方式。這允許我們保持業(yè)務對象獨立于每個業(yè)務對象中重復的事務劃分代碼。此外,事務行為和隔離層次的變化可以通過一個配置文件來改變而不需要對業(yè)務對象的實現(xiàn)造成影響。<beans>.<bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"><property name="sessionFactory"&g

35、t;<ref bean="mySessionFactory"/></property></bean><bean id="myTransactionInterceptor" class="erceptor.TransactionInterceptor"><property name="transactionManager"><ref bean="myTransactionM

36、anager"/></property><property name="transactionAttributeSource"><value>product.ProductService.increasePrice*=PROPAGATION_REQUIREDproduct.ProductService.someOtherBusinessMethod=PROPAGATION_MANDATORY</value></property></bean><bean id="myPro

37、ductServiceTarget" class="product.ProductServiceImpl"><property name="productDao"><ref bean="myProductDao"/></property></bean><bean id="myProductService" class="org.springframework.aop.framework.ProxyFactoryBean">

38、;<property name="proxyInterfaces"><value>product.ProductService</value></property><property name="interceptorNames"><list><value>myTransactionInterceptor</value><value>myProductServiceTarget</value></list></prop

39、erty></bean></beans>public class ProductServiceImpl implements ProductService private ProductDao productDao;public void setProductDao(ProductDao productDao) ductDao = productDao;public void increasePriceOfAllProductsInCategory(final String category) List productsToChange = thi

40、ductDAO.loadProductsByCategory(category);. 如同使用HibernateInterceptor一樣,TransactionInterceptor允許任何checked application exception從回調(diào)代碼中拋出,而TransactionTemplate受回調(diào)限制在其部拋出unchecked exceptions,在出現(xiàn)一個unchecked application exception的情況時,TransactionTemplate將引發(fā)一個回滾或者這個事務由應用(通過事務狀態(tài))標記為回滾。 TransactionIntercep

41、tor默認情況也是同樣的行為,但是允許為每一個方法制定回滾策略。 建立聲明性事務的一個便利的方式是使用TransactionProxyFactoryBean,特別是如果沒有其他AOP攔截器的話, TransactionProxyFactoryBean將聯(lián)合定義為代理的自身與一個特殊的目標Bean的事務配置。這將減少一個代理Bean對應一個目標Bean的配置情況。此外,你不必指定哪個接口或者哪個類必須定義事務方法。<beans>.<bean id="myTransactionManager" class="org.springframework.o

42、rm.hibernate.HibernateTransactionManager"><property name="sessionFactory"><ref bean="mySessionFactory"/></property></bean><bean id="myProductServiceTarget" class="product.ProductServiceImpl"><property name="product

43、Dao"><ref bean="myProductDao"/></property></bean><bean id="myProductService" class="erceptor.TransactionProxyFactoryBean"><property name="transactionManager"><ref bean="myTransact

44、ionManager"/></property><property name="target"><ref bean="myProductServiceTarget"/></property><property name="transactionAttributes"><props><prop key="increasePrice*">PROPAGATION_REQUIRED</prop><prop

45、key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop></props></property></bean></beans>7. 事務管理策略 對于Hibernate應用來說,無論是TransactionTemplate還是TransactionInterceptor都是委托驗實際的事務處理給PlatformTransactionManager實例,可以是一個HibernateTransactionManager(由一個單一的 Hibernate的S

46、essionFactory,使用一個ThreadLocal Session)或者可以是一個JtaTransactionManager(代理容器的JTA子系統(tǒng))。甚至你可以使用一個自定義的 PlatformTransactionManager實現(xiàn)。 如果選擇從本地Hibernate事務管理轉為由JTA來進行事務管理,例如:當你的應用的部署面對分布的事務需求時,也僅僅是改變一下配置的事。只要簡單地將Hibernate的事務管理換為JTA事務實現(xiàn)即可。所有的事務劃分和數(shù)據(jù)訪問無需做任何變動仍可以繼續(xù)工作,因為他們使用的都是普通的事務管理API。 對于分布式的事務會跨越多個Hibernate的sess

47、ion factories,僅僅是聯(lián)合JtaTransactionManager與多個LocalSessionFactoryBean定義作為事務策略。你的每一個DAO將通過它們各自的Bean屬性得到一個特殊的SessionFactory的引用。如果這一切都是在下面的JDBC數(shù)據(jù)源是事務容器,一個業(yè)務對象可以劃分事務跨越很多DAO和很多session factories而無需做特別的處理,對于使用JtaTransactionManager做為事務策略也是一樣的。<beans><bean id="myDataSource1" class="org.s

48、pringframework.jndi.JndiObjectFactoryBean"><property name="jndiName"><value>jdbc/myds1</value></property></bean><bean id="myDataSource2" class="org.springframework.jndi.JndiObjectFactoryBean"><property name="jndiName&q

49、uot;><value>jdbc/myds2</value></property></bean><bean id="mySessionFactory1" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"><property name="mappingResources"><list><value>product.hbm.xml</value>

50、</list></property><property name="hibernateProperties"><props><prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop></props></property><property name="dataSource"><ref bean="myDataSource1&

51、quot;/></property></bean><bean id="mySessionFactory2" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"><property name="mappingResources"><list><value>inventory.hbm.xml</value></list></property><

52、;property name="hibernateProperties"><props><prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop></props></property><property name="dataSource"><ref bean="myDataSource2"/></property></

53、bean><bean id="myTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/><bean id="myProductDao" class="product.ProductDaoImpl"><property name="sessionFactory"><ref bean="mySessionFactory1&q

54、uot;/></property></bean><bean id="myInventoryDao" class="product.InventoryDaoImpl"><property name="sessionFactory"><ref bean="mySessionFactory2"/></property></bean><bean id="myProductServiceTarget" clas

55、s="product.ProductServiceImpl"><property name="productDao"><ref bean="myProductDao"/></property><property name="inventoryDao"><ref bean="myInventoryDao"/></property></bean><bean id="myProductServic

56、e" class="erceptor.TransactionProxyFactoryBean"><property name="transactionManager"><ref bean="myTransactionManager"/></property><property name="target"><ref bean="myProductServiceTarge

57、t"/></property><property name="transactionAttributes"><props><prop key="increasePrice*">PROPAGATION_REQUIRED</prop><prop key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop></props></property></bean&

58、gt;</beans> 無論是HibernateTransactionManager還是JtaTransactionManager允許適當?shù)膶ibernate的在 JVM層次的緩存處理-不需要容器-提供特殊的事務查找或者JCA連接器(只要不使用E發(fā)起事務)。另外, HibernateTransactionManager能輸出JDBC連接供通常的JDBC訪問代碼使用。這樣就允許在高層次上的事務劃分是混合了 Hibernate與JDBC而不要JTA的,只要只是訪問一個數(shù)據(jù)庫就可以!8. 使用Spring管理應用的Bean 一個Spring應用配置定義可以加載實現(xiàn)多種配置,從FileS

59、ystemXmlApplicationContext和ClassPathXmlApplicationContext到XmlWebApplicationContext。這就允許在各種環(huán)境下重用 Spring管理的數(shù)據(jù)訪問和業(yè)務對象。默認情況下,一個Web應用都將有它自己的配置文件“WEB- INF/applicationContext.xml”。 在任何Spring應用中,一個應用配置定義在一個XML格式的文件中用來對應用的所有有關的Bean進行裝配,從Hibernate的 session factory到自定義的數(shù)據(jù)訪問和業(yè)務對象(象上面所有的Bean那樣)。他們中的大多數(shù)不需要Spring容

60、器知道他們,甚至即使是與其他Bean合作時也一樣,因為他們只是簡單的JavaBean之間的協(xié)作。下面的Bean定義可能是一個Spring Web 的MVC配置中用來訪問業(yè)務對象的配置的一部分。<bean id="myProductList" class="product.ProductListController"><property name="productService"><ref bean="myProductService"/></property></bean> Spring的Web控制器經(jīng)由Bean引用擁有它們需要的所有的業(yè)務和數(shù)據(jù)訪問對象,因此它們無需在應用配置中做任何手工的Bean查找。但是當使用 Spring管理的Beans用于Struts或者是在E實現(xiàn),或者一個applet中時常常是需要必須手工查找一個Bean的。因此Spring的 Bean可以被用在任何地方。也許只是需要是一應用配置的引用,或者經(jīng)由一個web容器的Servlet配置屬性,或者從一個文件中或者類路徑的資源中創(chuàng)建它。ApplicationContext co

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論