在使用struts+spring+hibernate的開發(fā)中,有些時候用戶會有數(shù)據(jù)庫存儲文件的需求,在數(shù)據(jù)庫中一般會采用
Blob字段或Clob字段來存儲二進制圖片、流媒體或文件。現(xiàn)就將在實際開發(fā)中遇到的問題及解決方法告之。
一、問題需求:
1.在持久化類中字段該用什么類型?
2.在Struts中文件對應(yīng)的數(shù)據(jù)類型是什么?
3.在Hibernate中字段對應(yīng)的類型是什么?
4.如何在Spring中處理這些文件?
二、解決方法:
1.在數(shù)據(jù)庫中這些文件最終是以字節(jié)的形式存儲二進制對象,所以在持久化類中將相應(yīng)的屬性定義為byte[]類型。
2.在Struts中可以使用<html:file property="" />標(biāo)簽來上傳文件,所以與之對應(yīng)的ActionForm的屬性類型為:
FormFile(org.apache.struts.upload.FormFile)類型,即使是使用了動態(tài)Form同理也是使用該類型.
提示:同時要將form標(biāo)簽修改為<html:form action="/Action.do" method="post" enctype="multipart/form-data">
以支持文件上傳后取得上傳數(shù)據(jù)。在給持久對象賦值時只需調(diào)用(FormFile) form.get("property")).getFileData();
方法即可返回byte[]。
3.在Hibernate中文件列對應(yīng)的類型可以是org.springframework.orm.hibernate3.support.BlobByteArrayType,
org.springframework.orm.hibernate3.support.ClobStringType、clob、blob、binary。什么時候用BlobBYteArrayType
什么時候用ClobStringType?一般如果要處理的對象是數(shù)據(jù)庫字段類型是blob時(主要是圖片,二進制對象等),
映射文件設(shè)置為:org.springframework.orm.hibernate3.support.BlobByteArrayType 數(shù)據(jù)庫字段是clob(大文本對象)
類型時,要將java的屬性的類型定為String,映射文件設(shè)置為: org.springframework.orm.hibernate3.support.ClobStringType。
4.如果在spring上要使用Struts中自帶的上傳功能必須在spring的配置文件中加以聲明.否者將會出現(xiàn)?
簀ava.lang.IllegalStateException: No LobHandler found for configuration - lobHandler property
must be set on LocalSessionFactoryBean異常。配置如下:
(1).聲明一個處理句柄:
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" />
(2).在sessionFactory中注入lobHandler:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="lobHandler" ref="lobHandler"/>
</bean>
提示: 指定lobHandler時,對于MySQL、DB2、MS SQL Server、Oracle 10g,使用DefaultLobHandler即可,而Oracle 9i,
則可以使用OracleLobHandler。因為Oracle9i處理lob的方式和不太一樣,所以這里要用spring提供的SimpleNativeJdbcExtractor.處理Oracle9i lob類型的特殊聲明:
<bean id="nativeJdbcExtractor" lazy-init="true" class="org.springframework.jdbc.support.nativejdbc.
SimpleNativeJdbcExtractor"/>
<bean id="lobHandler" lazy-init="true" class="org.springframework.jdbc.support.lob.OracleLobHandler">
<property name="nativeJdbcExtractor">
<ref bean="nativeJdbcExtractor"/>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 為處理Blob類型字段的句柄聲明 -->
<property name="lobHandler">
<ref local="lobHandler" />
</property>
</bean>
同時還應(yīng)該使用對應(yīng)的JDBC驅(qū)動。
Clob字段定義:<property name="屬性名" column="列名" type="org.springframework.orm.hibernate.support.ClobStringType"
length="1048"/>這里的length是指字節(jié),最大可以到2G.該字段在java對象中聲明為String類型。
如果使用的是mysql數(shù)據(jù)庫其默認(rèn)的上傳文件大小只有1047552字節(jié):如果上傳的文件大于1047552字節(jié)則會出現(xiàn)異常
org.springframework.jdbc.UncategorizedSQLException: You can change this value on the server by setting
the max_allowed_packet' variable.根據(jù)提示可以修改mysql數(shù)據(jù)庫的max_allowed_packet屬性大小。
打開my.ini文件中找到# SERVER SECTION后在port=3306下面加上max_allowed_packet=?M 修改完后重啟mysql服務(wù)即可成功上傳。
轉(zhuǎn)自:http://xinzhiz.javaeye.com/blog/111731