往数据库里存图片BLOB大字段出错
我在网上找的存图片的程序,但是一直报错如下:
Exception in thread "main" java.lang.UnsupportedOperationException
at sun.jdbc.odbc.JdbcOdbcResultSet.getBlob(Unknown Source)
at blob.OracelBlobTest.writeBlob(OracelBlobTest.java:90)
at blob.OracelBlobTest.main(OracelBlobTest.java:154)
这个语句有错误: blob = (BLOB)rst.getBlob(1);
求达人帮忙~~~
程序如下:
package blob;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import oracle.sql.BLOB;
/**
* 总结:
* 1.JDBC的API:java.sql.Blob接口,只提供了BLOB的读取方法,没有提供写入的方法。
* 2.ORACEL的API:oracle.sql.BLOB是一个类,它实现了java.sql.Blob接口,并且提供了向BLOB中写入数据的方法
* 3.在向数据库中插入BLOB时,只能用ORACEL提供的API:oracel.sql.BLOB
* 写入的步骤:1>插入一条记录,其中BLOB字段用oracle的空函数:empty_blob()代替。
* 2>以加锁的方式读取刚插入的记录,
* 3>利用oracle的oracle.sql.BLOB的getBinaryOutputStream()方法获取BLOB字段的输出流,向流中写入数据
* 4>用被写入的BLOB数据,更新原记录
* 4.在从数据库中读取BLOB时,既可以使用java.sql.Blob,也可以使用oracel.sql.BLOB
* 读取的步骤:1>读取记录,获取BLOB字段的输入流,
* 2>读取输入流中的数据,保存到一个地方。
*/
public class OracelBlobTest {
private Connection conn;
private final String DB_URL = "jdbc:odbc:oracle";
private final String DB_DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver";
private final String DB_USER= "system";
private final String DB_PASS= "123456";
/**
* 获取数据库连接
*/
private void initConnection() throws Exception {
if(conn == null || conn.isClosed()){
Class.forName(DB_DRIVER);
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
conn.setAutoCommit(false);
}
}
private void closeConnection(ResultSet rst, PreparedStatement psmt, Connection conn) throws Exception {
if(rst != null){
rst.close();
}
if(psmt != null){
psmt.close();
}
if(conn != null){
conn.close();
}
}
public OracelBlobTest() {
try {
initConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将指定文件写入到数据库中去。
* 注意:因为JDBC中的API没有提供写入BLOB的方法,所以这里用到了oracle的API:oracle.sql.BLOB;它实现了接口:java.sql.Blob,同时提供了写入BLOB的方法。
* 这里不能用java.sql.Blob
*/
@SuppressWarnings("deprecation")
public void writeBlob(String file) throws Exception {
// 1.插入一条记录,其中blob字段用空函数代替
// 2.以加锁的方式读取该记录
// 3.向blob字段写数据,并执行更新操作。
// 4.提交事务,关闭资源
// 1.
String sql = "insert into MYTABLE (ID, PIC) values (?, empty_blob())";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setString(1, "200921090149");
psmt.executeUpdate();
// 2.
BLOB blob = null;
OutputStream os = null;
InputStream is = new FileInputStream(file);
sql = "select PIC from MYTABLE where ID = ? for update";
psmt = null;
psmt = conn.prepareStatement(sql);
psmt.setString(1, "200921090149");
ResultSet rst = psmt.executeQuery();
if(rst != null && rst.next()){
blob = (BLOB)rst.getBlob(1);
// 利用oracle.sql.BLOB得到一个输出流,然后可以向输出流中写入数据。
os = blob.getBinaryOutputStream();
}
// 3.
byte[] b = new byte[1024];
int len = is.read(b);
while(len != -1){
os.write(b, 0, len);
len = is.read(b);
}
// 关闭流,此时会自动清空缓冲区。
is.close();
os.close();
sql = "update MYTABLE set PIC = ? where ID = ?";
psmt = null;
psmt = conn.prepareStatement(sql);
psmt.setBlob(1, blob);
psmt.setString(2, "200921090149");
psmt.executeUpdate();
// 4.
conn.commit();
closeConnection(rst, psmt, conn);
}
/**
* 注意:java.sql.Blob提供了一个getBinaryStream()方法,可以用来操作输入流,从中读取数据即可。
* 这里也可以用oracle.sql.BLOB
*/
public void getBlob(String ID, String distFile) throws Exception {
// 1.读取BLOB,
// 2.从BLOB中获取输入流,再从输入流中读取数据
// 3.关闭资源。
// 1.
String sql = "select PIC from MYTABLE where ID= ?";
PreparedStatement psmt = conn.prepareStatement(sql);
psmt.setString(1, ID);
ResultSet rst = psmt.executeQuery();
// 这里用到的是java.sql.Blob,而不是oracle.sql.BLOB [其实2者都可以的。]
BLOB blob = null;
InputStream is = null;
OutputStream os = new FileOutputStream(distFile);
// 2.
while(rst != null && rst.next()){
blob = (BLOB)rst.getBlob(1);
is = blob.getBinaryStream();
}
byte[] b = new byte[1024];
int len = is.read(b);
while(len != -1){
os.write(b, 0, len);
len = is.read(b);
}
// 3.
os.flush();
os.close();
is.close();
closeConnection(rst, psmt, conn);
}
public static void main(String[] args) throws Exception {
OracelBlobTest test = new OracelBlobTest();
// 测试写入BLOB
test.writeBlob("d:\\1.jpg");
// 测试读取BLOB
//test.getBlob("200921090149", "d:\\2.jpg");
}
}
[解决办法]
// 这里用到的是java.sql.Blob,而不是oracle.sql.BLOB [其实2者都可以的。]
BLOB blob = null;
在这里的申明直接使用oracle.sql.BLOB
在出错的那个位置使用
(oracle.sql.BLOB)rst.getBlob(1);