心的方向

          新的征途......
          posts - 75,comments - 19,trackbacks - 0

          Struts+Spring+Hibernate實現(xiàn)上傳下載(二)

          轉(zhuǎn)自:http://lihaiyan.javaeye.com/blog/127795

          數(shù)據(jù)持久層

            1、領域?qū)ο蠹坝成湮募?br />
            您可以使用Hibernate Middlegen、HIbernate Tools、Hibernate Syhchronizer等工具或手工的方式,編寫Hibernate的領域?qū)ο蠛陀成湮募F渲袑猅_FILE表的領域?qū)ο骉file.java為:

            代碼 1 領域?qū)ο骉file

          1. package sshfile.model;
          2. public class Tfile
          3.{
          4. private String fileId;
          5. private String fileName;
          6. private byte[] fileContent;
          7. private String remark;
          8. …//getter and setter
          9. }

            特別需要注意的是:數(shù)據(jù)庫表為Blob類型的字段在Tfile中的fileContent類型為byte[]。Tfile的Hibernate映射文件Tfile.hbm.xml放在Tfile .java類文件的相同目錄下:

            代碼 2 領域?qū)ο笥成湮募?br />
          1. <?xml version="1.0"?>
          2. <!DOCTYPE hibernate-mapping PUBLIC
          3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
          5. <hibernate-mapping>
          6. <class name="sshfile.model.Tfile" table="T_FILE">
          7. <id name="fileId" type="java.lang.String" column="FILE_ID">
          8. <generator class="uuid.hex"/>
          9. </id>
          10. <property name="fileContent"
          11. type="org.springframework.orm.hibernate3.support.BlobByteArrayType"
          12. column="FILE_CONTENT" lazy="true"/>
          13. …//其它一般字段的映射
          14. </class>
          15. </hibernate-mapping>

            fileContent字段映射為Spring所提供的BlobByteArrayType類型,BlobByteArrayType是用戶自定義的數(shù)據(jù)類型,它實現(xiàn)了Hibernate 的org.hibernate.usertype.UserType接口。BlobByteArrayType使用從sessionFactory獲取的Lob操作句柄lobHandler將byte[]的數(shù)據(jù)保存到Blob數(shù)據(jù)庫字段中。這樣,我們就再沒有必要通過硬編碼的方式,先insert然后再update來完成Blob類型數(shù)據(jù)的持久化,這個原來難伺候的老爺終于被平民化了。關于lobHandler的配置請見本文后面的內(nèi)容。

            此外lazy="true"說明地返回整個Tfile對象時,并不返回fileContent這個字段的數(shù)據(jù),只有在顯式調(diào)用tfile.getFileContent()方法時才真正從數(shù)據(jù)庫中獲取fileContent的數(shù)據(jù)。這是Hibernate3引入的新特性,對于包含重量級大數(shù)據(jù)的表字段,這種抽取方式提高了對大字段操作的靈活性,否則加載Tfile對象的結(jié)果集時如果總是返回fileContent,這種批量的數(shù)據(jù)抽取將可以引起數(shù)據(jù)庫的"洪泛效應"。

            2、DAO編寫和配置

            Spring強調(diào)面向接口編程,所以我們將所有對Tfile的數(shù)據(jù)操作的方法定義在TfileDAO接口中,這些接口方法分別是:

            ·findByFildId(String fileId)

            ·save(Tfile tfile)

            ·List findAll()

            TfileDAOHibernate提供了對TfileDAO接口基于Hibernate的實現(xiàn),如代碼 3所示:

            代碼 3 基于Hibernate 的fileDAO實現(xiàn)類

          1. package sshfile.dao;
          2.
          3. import sshfile.model.*;
          4. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
          5. import java.util.List;
          6.
          7. public class TfileDAOHibernate
          8. extends HibernateDaoSupport implements TfileDAO
          9. {
          10. public Tfile findByFildId(String fileId)
          11. {
          12. return (Tfile) getHibernateTemplate().get(Tfile.class, fileId);
          13. }
          14. public void save(Tfile tfile)
          15. {
          16. getHibernateTemplate().save(tfile);
          17. getHibernateTemplate().flush();
          18. }
          19. public List findAll()
          20. {
          21. return getHibernateTemplate().loadAll(Tfile.class);
          22. }
          23. }

            TfileDAOHibernate通過擴展Spring提供的Hibernate支持類HibernateDaoSupport而建立,HibernateDaoSupport封裝了HibernateTemplate,而HibernateTemplate封裝了Hibernate所提供幾乎所有的的數(shù)據(jù)操作方法,如execute(HibernateCallback action),load(Class entityClass, Serializable id),save(final Object entity)等等。

            所以我們的DAO只需要簡單地調(diào)用父類的HibernateTemplate就可以完成幾乎所有的數(shù)據(jù)庫操作了。

            由于Spring通過代理Hibernate完成數(shù)據(jù)層的操作,所以原Hibernate的配置文件hibernate.cfg.xml的信息也轉(zhuǎn)移到Spring的配置文件中:

            代碼 4 Spring中有關Hibernate的配置信息

          1. <beans>
          2. <!-- 數(shù)據(jù)源的配置 //-->
          3. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          4. destroy-method="close">
          5. <property name="driverClassName" value="http://www.zhmy.com/oracle.jdbc.driver.OracleDriver"/>
          6. <property name="url" value="jdbc:oracle:thin:@localhost:1521:ora9i"/>
          7. <property name="username" value="test"/>
          8. <property name="password" value="test"/>
          9. </bean>
          10. <!-- Hibernate會話工廠配置 //-->
          11. <bean id="sessionFactory"
          12. class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
          13. <property name="dataSource" ref="dataSource"/>
          14. <property name="mappingDirectoryLocations">
          15. <list>
          16. <value>classpath:/sshfile/model</value>
          17. </list>
          18. </property>
          19. <property name="hibernateProperties">
          20. <props>
          21. <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
          22. <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
          23. </props>
          24. </property>
          25. </bean>
          26. <!-- Hibernate 模板//-->
          27. <bean id="hibernateTemplate"
          28. class="org.springframework.orm.hibernate3.HibernateTemplate">
          29. <property name="sessionFactory" ref="sessionFactory"/>
          30. </bean>
          31. <!--DAO配置 //-->
          32. <bean id="tfileDAO" class="sshfile.dao.TfileDAOHibernate">
          33. <property name="hibernateTemplate" ref="hibernateTemplate" />
          34. </bean>
          35. …
          36. </beans>

            第3~9行定義了一個數(shù)據(jù)源,其實現(xiàn)類是apache的BasicDataSource,第11~25行定義了Hibernate的會話工廠,會話工廠類用Spring提供的LocalSessionFactoryBean維護,它注入了數(shù)據(jù)源和資源映射文件,此外還通過一些鍵值對設置了Hibernate所需的屬性。

            其中第16行通過類路徑的映射方式,將sshfile.model類包目錄下的所有領域?qū)ο蟮挠成湮募b載進來,在本文的例子里,它將裝載進Tfile.hbm.xml映射文件。如果有多個映射文件需要聲明,使用類路徑映射方式顯然比直接單獨指定映射文件名的方式要簡便。

            第27~30行定義了Spring代理Hibernate數(shù)據(jù)操作的HibernateTemplate模板,而第32~34行將該模板注入到tfileDAO中。

            需要指定的是Spring 1.2.5提供了兩套Hibernate的支持包,其中Hibernate 2相關的封裝類位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封裝類位于org.springframework.orm.hibernate3.*包中,需要根據(jù)您所選用Hibernate版本進行正確選擇。

            3、Lob字段處理的配置

            我們前面已經(jīng)指出Oracle的Lob字段和一般類型的字段在操作上有一個明顯的區(qū)別--那就是你必須首先通過Oracle的empty_blob()/empty_clob()初始化Lob字段,然后獲取該字段的引用,通過這個引用更改其值。所以要完成對Lob字段的操作,Hibernate必須執(zhí)行兩步數(shù)據(jù)庫訪問操作,先Insert再Update。

            使用BlobByteArrayType字段類型后,為什么我們就可以象一般的字段類型一樣操作Blob字段呢?可以確定的一點是:BlobByteArrayType不可能逾越Blob天生的操作方式,原來是BlobByteArrayType數(shù)據(jù)類型本身具體數(shù)據(jù)訪問的功能,它通過LobHandler將兩次數(shù)據(jù)訪問的動作隱藏起來,使Blob字段的操作在表現(xiàn)上和其他一般字段業(yè)類型無異,所以LobHandler即是那個"苦了我一個,幸福十億人"的那位幕后英雄。

            LobHandler必須注入到Hibernate會話工廠sessionFactory中,因為sessionFactory負責產(chǎn)生與數(shù)據(jù)庫交互的Session。LobHandler的配置如代碼 5所示:

            代碼 5 Lob字段的處理句柄配置

          1. <beans>
          2. …
          3. <bean id="nativeJdbcExtractor"
          4. class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"
          5. lazy-init="true"/>
          6. <bean id="lobHandler"
          7. class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">
          8. <property name="nativeJdbcExtractor">
          9. <ref local="nativeJdbcExtractor"/>
          10. </property>
          11. </bean>
          12. …
          13. </beans>

            首先,必須定義一個能夠從連接池中抽取出本地數(shù)據(jù)庫JDBC對象(如OracleConnection,OracleResultSet等)的抽取器:nativeJdbcExtractor,這樣才可以執(zhí)行一些特定數(shù)據(jù)庫的操作。對于那些僅封裝了Connection而未包括Statement的簡單數(shù)據(jù)連接池,SimpleNativeJdbcExtractor是效率最高的抽取器實現(xiàn)類,但具體到apache的BasicDataSource連接池,它封裝了所有JDBC的對象,這時就需要使用CommonsDbcpNativeJdbcExtractor了。Spring針對幾個著名的Web服務器的數(shù)據(jù)源提供了相應的JDBC抽取器:

            ·WebLogic:WebLogicNativeJdbcExtractor

            ·WebSphere:WebSphereNativeJdbcExtractor

            ·JBoss:JBossNativeJdbcExtractor

            在定義了JDBC抽取器后,再定義lobHandler。Spring 1.2.5提供了兩個lobHandler:

            ·DefaultLobHandler:適用于大部分的數(shù)據(jù)庫,如SqlServer,MySQL,對Oracle 10g也適用,但不適用于Oracle 9i(看來Oracle 9i確實是個怪胎,誰叫Oracle 公司自己都說Oracle 9i是一個過渡性的產(chǎn)品呢)。

            ·OracleLobHandler:適用于Oracle 9i和Oracle 10g。

            由于我們的數(shù)據(jù)庫是Oracle9i,所以使用OracleLobHandler。

            在配置完LobHandler后, 還需要將其注入到sessionFactory的Bean中,下面是調(diào)用后的sessionFactory Bean的配置:

            代碼 6 將lobHandler注入到sessionFactory中的配置

          1. <beans>
          2. …
          3. <bean id="sessionFactory"
          4. class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
          5. <property name="dataSource" ref="dataSource"/>
          6. <!-- 為處理Blob類型字段的句柄聲明 //-->
          7. <property name="lobHandler" ref="lobHandler"/>
          8. …
          9. </bean>
          10. …
          11. </beans>

            如第7所示,通過sessionFactory的lobHandler屬性進行注入。


          posted on 2008-04-10 14:55 阿偉 閱讀(292) 評論(0)  編輯  收藏 所屬分類: 框架整合
          主站蜘蛛池模板: 莱阳市| 北海市| 临西县| 孝昌县| 两当县| 财经| 香港| 东阿县| 当阳市| 浑源县| 商都县| 赤城县| 深水埗区| 大新县| 晋州市| 海原县| 英山县| 和田县| 珠海市| 都安| 始兴县| 剑河县| 商都县| 临海市| 景泰县| 惠安县| 临武县| 松潘县| 寻甸| 图片| 东港市| 东山县| 淮北市| 昌邑市| 乐安县| 庆元县| 寿阳县| 安多县| 平南县| 巴林右旗| 乌拉特后旗|