create table textblob (tid number(38,0),lob blob)
然後建立對應的Java對象
public class testblob {
private long id;
private byte[] lob;
//set和get方法略...
}
最後是Hibernate配置和映射文件。
<hibernate-configuration> <session-factory> <property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver </property> <property name="connection.url"> jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:orcl </property> <property name="connection.useUnicode">true</property> <property name="connection.characterEncoding">UTF-8</property> <property name="connection.username">xxxxxx</property> <property name="connection.password">xxxxxx</property> <property name="hibernate.connection.provider_class"> org.hibernate.connection.C3P0ConnectionProvider </property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.timeout">120</property> <property name="hibernate.c3p0.max_statements">100</property> <property name="hibernate.c3p0.idle_test_period">120</property> <property name="hibernate.c3p0.acquire_increment">2</property> <property name="hibernate.connection.SetBigStringTryClob"> true </property> <property name="hibernate.jdbc.use_streams_for_binary"> true </property> <property name="dialect"> org.hibernate.dialect.Oracle9Dialect </property> <property name="hibernate.show_sql">true</property> <property name="hibernate.transaction.factory_class"> org.hibernate.transaction.JDBCTransactionFactory </property> <mapping resource="org/Miao/testblob.hbm.xml" /> </session-factory> </hibernate-configuration>
注意配置文件中“hibernate.jdbc.use_streams_for_binary”這個部分。這是Oracle必須添加的屬性。其它配置沒有什麼特別的。SQL Server不需要這個屬性。同時配置文件配置了一個C3P0數據庫連接池。
映射文件如下:
<hibernate-mapping package="org.Miao"> <class name="testblob" table="tblob"> <id name="id" column="tid"> <generator class="native"></generator> </id> <property name="lob" column="tlob" type="binary"> </property> </class> </hibernate-mapping>
然後就可以測試一下了。寫一個運行的測試類Run.class。
public class run {
public static void main(String[] args) {
Configuration configuration = new Configuration();
configuration.configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
File f = new File("d:/f.exe");
byte[] tmp = new byte[(int) f.length()];
try {
FileInputStream fi = new FileInputStream(f);
fi.read(tmp);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
testblob test = new testblob();
test.setId(5);
test.setLob(tmp);
Transaction t = session.beginTransaction();
try {
session.saveOrUpdate(test);
t.commit();
} catch (HibernateException e) {
e.printStackTrace();
t.rollback();
} finally {
session.close();
}
}
}
現在進入數據庫的話,可以看到數據庫記錄中已經增加了一條,文件已經被保存到數據庫裏了。但是,這麼做有一個很大的問題,那就是內存。在Eclipse+WTP的環境下,加入的文件稍微大一點,就會造成OutofMemony異常。因爲用這種方法存入數據庫,需要把文件全部讀入內存纔可以。文件一大,就會造成內存溢出,即使把JVM使用的內存調大,保存大文件也是非常慢的。我的調試環境,存一個10M的文件,單用戶Tomcat(內存調整到256-512M)跑,Oracle10g又是遠程,需要好幾分鐘。多用戶條件下,性能可想而知。而且,一旦多用戶同時保存或同時讀取大文件,立馬會造成內存佔用暴增,最後溢出。所以,使用這種方式處理Blob,一定要注意,不要保存大文件,我覺得最好不要超過1M。