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。