最近项目要用到往Oracle中的BLOB字段插入图片或者文档什么之类的。其实往Oracle中插入BLOB这个东西在网上有很多解决方法。但是我这里是公司自己的框架,用的是Spring的架构来进行所有的操作,同时还用了DBCP的数据连接池。所以网上找了很多资料,现在我就简单的总结综合一下。
我这里是Oracle 9i,必须使用OracleLobHandler 才可以,如果是其他的数据库,直接使用DefaultLobHandler就可以了,这个在网上有很多资料。
但是由于使用了数据连接池,所以必须通过Spring获取原始的数据连接。两种方法:
第一种:通过Spring的Bean配置,获取原始数据连接。
Spring配置:
<bean id="commonsDbcpNativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" />
Java代码获取连接:
Connection con = getJdbcTemplate().getDataSource().getConnection();
CommonsDbcpNativeJdbcExtractor commonsForOracleConnection = (CommonsDbcpNativeJdbcExtractor) SpringUtils.getSpringBean("commonsDbcpNativeJdbcExtractor");
Connection conoracle = commonsForOracleConnection.getNativeConnection(con);
然后使用原始的数据库连接来插入数据库:
conn.setAutoCommit(false);
InputStream is = (InputStream) request.getAttribute("UPLOAD_FILE");
BLOB blob = null;
PreparedStatement pstmt = conn.prepareStatement("select DOC_FILE from BILL_DOC where DOC_NO= ? for update");
pstmt.setInt(1, docid);
ResultSet rset = pstmt.executeQuery();
if (rset.next()) {
blob = (BLOB) rset.getBlob(1);
OutputStream out = blob.getBinaryOutputStream();
byte[] b = new byte[blob.getBufferSize()];
int len = 0;
while( (len = is.read(b)) != -1)
out.write(b,0,len);
is.close();
out.close();
conn.commit();
conn.close();
}
下面使用Spring来操作,其实使用Spring是非常简单的,因为Spring都封装好了:
Spring配置:
<bean id="nativeJdbcExtractor"
class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"
lazy-init="true" />
<bean id="lobHandler"
class="org.springframework.jdbc.support.lob.OracleLobHandler"
lazy-init="true">
<property name="nativeJdbcExtractor">
<ref local="nativeJdbcExtractor" />
</property>
</bean>
Java代码使用Spring上传
final JdbcTemplate jt = getJdbcTemplate();
LobHandler lobHandler = (OracleLobHandler) WebUtil.getBean(request.getSession().getServletContext(), "lobHandler");
jt.execute("UPDATE BILL_DOC SET DOC_FILE = ? WHERE DOC_NO = ?",
new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
@Override
protected void setValues(PreparedStatement ps,
LobCreator lobCreator) throws SQLException,DataAccessException {
// TODO Auto-generated method stub
try {
lobCreator.setBlobAsBinaryStream(ps, 1, data, (int) data.available());
ps.setLong(2, id);
} catch (Exception e) {
// TODO Auto-generated catch block
writer.write("OPERATION FAIL");
System.out.println("保函保存失败!" + e.getMessage());
e.printStackTrace();
} finally {
try {
data.close();
} catch (IOException e) {
System.out.println("流关闭失败!" + e.getMessage());
}
}
}
});