轉自:http://lihaiyan.javaeye.com/blog/127795
數據持久層
1、領域對象及映射文件
您可以使用Hibernate Middlegen、HIbernate Tools、Hibernate Syhchronizer等工具或手工的方式,編寫Hibernate的領域對象和映射文件。其中對應T_FILE表的領域對象Tfile.java為:
代碼 1 領域對象Tfile
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. } |
特別需要注意的是:數據庫表為Blob類型的字段在Tfile中的fileContent類型為byte[]。Tfile的Hibernate映射文件Tfile.hbm.xml放在Tfile .java類文件的相同目錄下:
代碼 2 領域對象映射文件
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是用戶自定義的數據類型,它實現了Hibernate 的org.hibernate.usertype.UserType接口。BlobByteArrayType使用從sessionFactory獲取的Lob操作句柄lobHandler將byte[]的數據保存到Blob數據庫字段中。這樣,我們就再沒有必要通過硬編碼的方式,先insert然后再update來完成Blob類型數據的持久化,這個原來難伺候的老爺終于被平民化了。關于lobHandler的配置請見本文后面的內容。
此外lazy="true"說明地返回整個Tfile對象時,并不返回fileContent這個字段的數據,只有在顯式調用tfile.getFileContent()方法時才真正從數據庫中獲取fileContent的數據。這是Hibernate3引入的新特性,對于包含重量級大數據的表字段,這種抽取方式提高了對大字段操作的靈活性,否則加載Tfile對象的結果集時如果總是返回fileContent,這種批量的數據抽取將可以引起數據庫的"洪泛效應"。
2、DAO編寫和配置
Spring強調面向接口編程,所以我們將所有對Tfile的數據操作的方法定義在TfileDAO接口中,這些接口方法分別是:
·findByFildId(String fileId)
·save(Tfile tfile)
·List findAll()
TfileDAOHibernate提供了對TfileDAO接口基于Hibernate的實現,如代碼 3所示:
代碼 3 基于Hibernate 的fileDAO實現類
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所提供幾乎所有的的數據操作方法,如execute(HibernateCallback action),load(Class entityClass, Serializable id),save(final Object entity)等等。
所以我們的DAO只需要簡單地調用父類的HibernateTemplate就可以完成幾乎所有的數據庫操作了。
由于Spring通過代理Hibernate完成數據層的操作,所以原Hibernate的配置文件hibernate.cfg.xml的信息也轉移到Spring的配置文件中:
代碼 4 Spring中有關Hibernate的配置信息
1. <beans>
2. <!-- 數據源的配置 //-->
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行定義了一個數據源,其實現類是apache的BasicDataSource,第11~25行定義了Hibernate的會話工廠,會話工廠類用Spring提供的LocalSessionFactoryBean維護,它注入了數據源和資源映射文件,此外還通過一些鍵值對設置了Hibernate所需的屬性。
其中第16行通過類路徑的映射方式,將sshfile.model類包目錄下的所有領域對象的映射文件裝載進來,在本文的例子里,它將裝載進Tfile.hbm.xml映射文件。如果有多個映射文件需要聲明,使用類路徑映射方式顯然比直接單獨指定映射文件名的方式要簡便。
第27~30行定義了Spring代理Hibernate數據操作的HibernateTemplate模板,而第32~34行將該模板注入到tfileDAO中。
需要指定的是Spring 1.2.5提供了兩套Hibernate的支持包,其中Hibernate 2相關的封裝類位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封裝類位于org.springframework.orm.hibernate3.*包中,需要根據您所選用Hibernate版本進行正確選擇。
3、Lob字段處理的配置
我們前面已經指出Oracle的Lob字段和一般類型的字段在操作上有一個明顯的區別--那就是你必須首先通過Oracle的empty_blob()/empty_clob()初始化Lob字段,然后獲取該字段的引用,通過這個引用更改其值。所以要完成對Lob字段的操作,Hibernate必須執行兩步數據庫訪問操作,先Insert再Update。
使用BlobByteArrayType字段類型后,為什么我們就可以象一般的字段類型一樣操作Blob字段呢?可以確定的一點是:BlobByteArrayType不可能逾越Blob天生的操作方式,原來是BlobByteArrayType數據類型本身具體數據訪問的功能,它通過LobHandler將兩次數據訪問的動作隱藏起來,使Blob字段的操作在表現上和其他一般字段業類型無異,所以LobHandler即是那個"苦了我一個,幸福十億人"的那位幕后英雄。
LobHandler必須注入到Hibernate會話工廠sessionFactory中,因為sessionFactory負責產生與數據庫交互的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> |
首先,必須定義一個能夠從連接池中抽取出本地數據庫JDBC對象(如OracleConnection,OracleResultSet等)的抽取器:nativeJdbcExtractor,這樣才可以執行一些特定數據庫的操作。對于那些僅封裝了Connection而未包括Statement的簡單數據連接池,SimpleNativeJdbcExtractor是效率最高的抽取器實現類,但具體到apache的BasicDataSource連接池,它封裝了所有JDBC的對象,這時就需要使用CommonsDbcpNativeJdbcExtractor了。Spring針對幾個著名的Web服務器的數據源提供了相應的JDBC抽取器:
·WebLogic:WebLogicNativeJdbcExtractor
·WebSphere:WebSphereNativeJdbcExtractor
·JBoss:JBossNativeJdbcExtractor
在定義了JDBC抽取器后,再定義lobHandler。Spring 1.2.5提供了兩個lobHandler:
·DefaultLobHandler:適用于大部分的數據庫,如SqlServer,MySQL,對Oracle 10g也適用,但不適用于Oracle 9i(看來Oracle 9i確實是個怪胎,誰叫Oracle 公司自己都說Oracle 9i是一個過渡性的產品呢)。
·OracleLobHandler:適用于Oracle 9i和Oracle 10g。
由于我們的數據庫是Oracle9i,所以使用OracleLobHandler。
在配置完LobHandler后, 還需要將其注入到sessionFactory的Bean中,下面是調用后的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
阿偉 閱讀(290)
評論(0) 編輯 收藏 所屬分類:
框架整合