一沙一世界, 一花一天堂。

ORACLE数据库文件写入读取

[Java] 韩玉龙 2016-05-16 16:36:54 点击率:2842次

文件上传一直使用的将文件上传到服务器某个文件夹下,数据中只存储文件地址
近段时间因为集群导致有些文件读取不到
在网上查了一些资料,解决办法有几种
1:做文件夹共享

2:将文件写入数据库

。。。


研究了一下将文件 写入数据库的方法,中途遇到了很多问题

首先几个在开发中对我很有用的帖子,给大家参考一下

我的文件向数据库写入及读取的代码大部分都是借鉴了该帖子
里面详细介绍了每个步骤
http://www.blogjava.net/sxt0823/archive/2008/06/15/86023.html


但遇到BLOB强转问题(困扰了好几天)
这个帖子给了我一些启发(对这句“网络上的教程99%都是行不通的”深有同感)
http://bbs.csdn.net/topics/60009941

将字段改为LONG RAW类型可以使用,但是一个表只能使用一次,而我的有四个字段需要


好了,说到这里当然要贴一下自己的解决办法,希望对大家有所帮助

下面是我的代码(我是四个图片,很多重复代码,这里精简了一下,就俩字段了id和img)

写入代码:

Connection conn = DataSourceUtils.getConnection(getDataSource());
conn.setAutoCommit(false);
//插入数据,BLOB CLOB字段插入空值
StringBuffer sql1 = new StringBuffer();
sql1.append("insert into tableName ( ");
sqlzmcl.append(" img_id, ");
sql1.append(" img_tp ");
sql1.append("   ) ");
sql1.append(" values (?, ?)");

PreparedStatement pst = conn.prepareStatement(sql1.toString());
pst.setInt(1, 1001);
pst.setBlob(2, BLOB.empty_lob());
pst.executeUpdate();
pst.close();

//再次从库表读出,获得Blob/Clob句柄
StringBuffer sqlquery = new StringBuffer();
sqlquery.append("select img_tp ");
sqlquery.append(" from tableName ");
sqlquery.append(" where img_id = ? ");
sqlquery.append(" for update ");

pst = conn.prepareStatement(sqlquery.toString());
pst.setInt(1, 1001);
ResultSet rst = pst.executeQuery();
rst.next();

//就是这里强转报异常(要注意BLOB和Blob的区别)
//oracle.sql.BLOB imgBlob = (oracle.sql.BLOB) rst.getBlob(1);
//将二进创数据写入Blob
FileInputStream inStream = new  FileInputStream("C:\\img.jpg");
//OutputStream outStream = imgBlob.getBinaryOutputStream();


//这样解决了一下
Object obj = rst.getBlob(1);
Class clazz = obj.getClass();
Method method = clazz.getMethod("getBinaryOutputStream", new Class[]{});
OutputStream outStream = (OutputStream)method.invoke(obj, new Object[]{});
BufferedOutputStream bos = new BufferedOutputStream(outStream);

byte[] buf = new byte[10240];//10K 读取缓存
int len;
while((len=inStream.read(buf))>0){
outStream.write(buf,0,len);
}
inStream.close();
outStream.close();

//将Blob/Clob字段更新到数据序
StringBuffer sqlupdate = new StringBuffer();
sqlupdate.append("update tableName set ");
sqlupdate.append(" img_tp = ? ");
sqlupdate.append(" where img_id = ? ");

pst = conn.prepareStatement(sqlupdate.toString());
pst.setBlob(1, (Blob) obj);
pst.setInt(2, 1001);
int num = pst.executeUpdate();
pst.close();
conn.commit();
conn.close();


读取代码:
Connection conn = DataSourceUtils.getConnection(getDataSource());
conn.setAutoCommit(false);

StringBuffer sql = new StringBuffer();
sqlquery.append("select img_tp ");
sqlquery.append(" from tableName ");
sqlquery.append(" where img_id = ? ");

PreparedStatement pst = conn.prepareStatement(sql.toString());
pst.setInt(1, 1001);
ResultSet rst = pst.executeQuery();
if(rst.next()){
Blob imgBlob = rst.getBlob("img_tp");
// 通过Blob.getBinaryS=ream()方法获取二进制流
InputStream inStream = imgBlob.getBinaryStream();
FileOutputStream outStream = new FileOutputStream("C:\\outimg.jpg");
byte[] buf = new byte[10240];//10K 读取缓存
int len;
while((len=inStream.read(buf))>0){
outStream.write(buf,0,len);
}
inStream.close();
outStream.close();
}