如果要將
將檔案存入資料庫,我們在JDBC中可以使用CLOB與BLOB來分別針對文字檔案與二進位檔案進行儲存,Spring中可以透過JdbcTemplate來處理CLOB與BLOB。
舉個例子來說,假設您的MySQL資料庫表格如下:
| CREATE TABLE test ( id INT AUTO_INCREMENT PRIMARY, txt TEXT, image BLOB );
|
假設我們現在分別讀進一個文字檔案與二進位檔案,並想將之儲存至資料庫中,則我們可以使用JdbcTemplate,例如:
| File binaryFile = File(); File txtFile = File();
InputStream is = FileInputStream(binaryFile); Reader reader = FileReader(txtFile);
JdbcTemplate jdbcTemplate = JdbcTemplate(dataSource);
LobHandler lobHandler = DefaultLobHandler();
jdbcTemplate.execute(, AbstractLobCreatingPreparedStatementCallback(lobHandler) setValues(PreparedStatement pstmt, LobCreator lobCreator) SQLException, DataAccessException lobCreator.setClobAsCharacterStream(pstmt, 1, reader, () txtFile.length()); lobCreator.setBlobAsBinaryStream(pstmt, 2, is, () binaryFile.length());
);
reader.close(); is.close();
|
JdbcTemplate中傳入了AbstractLobCreatingPreparedStatementCallback的實作,並傳入一 個 LobHandler,對於MySQL(MS SQL Server或Oracle 10g),這邊使用DefaultLobHandler即可,對於Oracle 9i特定的LOB處理,我們可以使用OracleLobHandler。
如果要從資料庫中將資料讀取出來,並另存為檔案,我們可以使用以下的程式:
| Writer writer = FileWriter(); OutputStream os = FileOutputStream( File());
jdbcTemplate.query(, Object[] Integer(1), AbstractLobStreamingResultSetExtractor() streamData(ResultSet rs) SQLException, IOException, DataAccessException FileCopyUtils.copy(lobHandler.getClobAsCharacterStream(rs, 1), writer); FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 2), os);
); writer.close(); os.close();
|
在使用Spring搭配Hibernate時,可以簡化對Lob型態的處理,只要在SessionFactory建構時指定LobHandler,例如:
* beans-config.xml
| <?xml version= encoding=?> <!DOCTYPE beans PUBLIC > <beans> <bean id= class=> <property name=> <value>com.mysql.jdbc.Driver</value> </property> <property name=> <value>jdbc:mysql: </property> <property name=> <value>root</value> </property> <property name=> <value>123456</value> </property> </bean>
<bean id= class=/>
<bean id= class= destroy-method=> <property name=> <ref bean=/> </property> <property name=> <ref bean=/> </property> <property name=> <list> <value>onlyfun/caterpillar/User.hbm.xml</value> </list> </property> <property name=> <props> <prop key=> org.hibernate.dialect.MySQLDialect </prop> </props> </property> </bean>
<bean id= class=> <property name=> <ref bean=/> </property> </bean> </beans>
|
在這邊指定LobHandler時,對於MySQL、DB2、MS SQL Server、Oracle 10g,使用DefaultLobHandler即可,而對於Oracle 9i,則可以使用OracleLobHandler。
接下來的操作與一般對HibernateTemplate的操作無異,例如您的資料庫表格為:
| CREATE TABLE user ( id INT auto_increment PRIMARY Key, txt TEXT, image BLOB );
|
Spring的ClobStringType可以將CLOB映射至String,而BlobByteArrayType可以將BLOB映射至byte[],所以我們可以設計一個User類別如下:
* User.java
| onlyfun.caterpillar;
User Integer id; String txt; [] image;
Integer getId() id;
setId(Integer id) this.id = id;
[] getImage() image;
setImage([] image) this.image = image;
String getTxt() txt;
setTxt(String txt) this.txt = txt;
|
Use.hbm.xml沒什麼特別的:
* User.hbm.xml
| <?xml version= encoding=?> <!DOCTYPE hibernate-mapping PUBLIC >
<hibernate-mapping> < name= table=>
<id name= column=> <generator class=/> </id>
<property name= column=/>
<property name= column=/> </class> </hibernate-mapping>
|
以下是個簡單的儲存與讀取Lob的程式片段示範:
| ApplicationContext context = FileSystemXmlApplicationContext();
InputStream is = FileInputStream( File()); [] b = [is.available()]; is.read(b); is.close();
User user = User(); user.setTxt(); user.setImage(b);
HibernateTemplate hibernateTemplate = (HibernateTemplate) context.getBean(); hibernateTemplate.save(user);
user = (User) hibernateTemplate.execute( HibernateCallback() Object doInHibernate(Session session) HibernateException, SQLException User user = (User) session.load(User.class, Integer(1)); Hibernate.initialize(user); user;
);
System.out.println(user.getTxt()); b = user.getImage();
OutputStream os = FileOutputStream( File()); os.write(b); os.close();
|