不依賴驅動更新blob字段,場景如下:
tomcat發佈到weblogic上,使用weblogic的連接池,就拋錯了,如下:
java.lang.ClassCastException: weblogic.jdbc.wrapper.Blob_oracle_sql_BLOB
開發代碼如下:
oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("TRANSFERDATA");
BufferedOutputStream bos = new BufferedOutputStream(blob.getBinaryOutputStream());
bos.write(define.getBytes("GBK"));
後來查了一下,原因是通過weblogic連接池取出的連接取出的blob對象是weblogic封裝過的OracleThinBlob,而不是oracle.sql.BLOB。然後又看了一下OracleThinBlob的方法與oracle.sql.BLOB類似,所以採用了下面的寫法,避免異常:
Object obj = rs.getBlob("TRANSFERDATA");
Class clazz = obj.getClass();
Method method = clazz.getMethod("getBinaryOutputStream", new Class[]{});
OutputStream os = (OutputStream)method.invoke(obj, new Object[]{});
BufferedOutputStream bos = new BufferedOutputStream(os);
bos.write(define.getBytes("GBK"));
/**
* 此方法用於執行對大對象進行操作的sql語句
* 傳入的參數:blob對象
*/
public boolean execUpdateBlobSQL(String sql, String tJSONObj){
PreparedStatement pstmt = null;
ResultSet rs = null;
//System.out.println("下面是預編譯ExecSQL...");
System.out.println("預編譯ExecSQL執行時間:"+new java.util.Date()+"; ExecSQL : " + sql);
if (!mflag){
con = DBConnPool.getConnection();
}
try{
con.setAutoCommit(false);//addbyefeng 關閉自動提交
pstmt = con.prepareStatement(StrTool.GBKToUnicode(sql));
//循環傳入的參數數據 將數組內的參數 賦值給 預編譯sql
rs = pstmt.executeQuery(sql);
while (rs.next())
{
//注:此處很重要。得到oracle.sql.BLOB對象後反射轉換爲BufferedOutputStream,目的是不依賴驅動
Object obj = rs.getBlob("TRANSFERDATA");
Class<? extends Object> clazz = obj.getClass();
Method method = clazz.getMethod("getBinaryOutputStream", new Class[]{});
OutputStream os = (OutputStream)method.invoke(obj, new Object[]{});
BufferedOutputStream outStream = new BufferedOutputStream(os);
outStream.write(tJSONObj.getBytes("GBK"), 0, tJSONObj.getBytes("GBK").length);
os.flush();
outStream.flush();
os.close();
outStream.close();
}
rs.close();
pstmt.close();
if (!mflag){
con.commit();
con.close();
}
}
catch (Exception e){
// @@錯誤處理
System.out.println("### Error ExeSQL at execUpdateSQL: " + sql);
CError.buildErr(this, e.toString(), mErrors);
try{
if (pstmt != null){
//由於描述的問題,導致執行的sql錯誤百出,因此pstmt的關閉需要特殊處理
try{
pstmt.close();
}
catch (SQLException ex){
ex.printStackTrace();
}
finally{
try{
System.out.println("Sql's bug is very big: " + sql);
pstmt.close();
}
catch (SQLException ex){}
}
}
if (!mflag){
con.rollback();
con.close();
}
}
catch (SQLException ex){
//在這個地方,有可能會沒有關閉連接
ex.printStackTrace();
return false;
}
return false;
}finally{
try {
if (rs != null) {
rs.close();
}
if (pstmt!=null) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return true;
}
/**
* 此方法用於執行對大對象進行操作的sql語句
* 傳入的參數:blob對象
*/
public boolean execSetBlobDataSQL(String sql, String tJSONObj, String tColumn){
PreparedStatement pstmt = null;
ResultSet rs = null;
//System.out.println("下面是預編譯ExecSQL...");
System.out.println("預編譯ExecSQL執行時間:"+new java.util.Date()+"; ExecSQL : " + sql);
if (!mflag){
con = DBConnPool.getConnection();
}
try{
con.setAutoCommit(false);//addbyefeng 關閉自動提交
pstmt = con.prepareStatement(StrTool.GBKToUnicode(sql));
//循環傳入的參數數據 將數組內的參數 賦值給 預編譯sql
rs = pstmt.executeQuery(sql);
while (rs.next())
{
//注:此處很重要。得到oracle.sql.BLOB對象後反射轉換爲BufferedOutputStream,目的是不依賴驅動
Object obj = rs.getBlob(tColumn);
Class<? extends Object> clazz = obj.getClass();
Method method = clazz.getMethod("getBinaryOutputStream", new Class[]{});
OutputStream os = (OutputStream)method.invoke(obj, new Object[]{});
BufferedOutputStream outStream = new BufferedOutputStream(os);
outStream.write(tJSONObj.getBytes("GBK"), 0, tJSONObj.getBytes("GBK").length);
os.flush();
outStream.flush();
os.close();
outStream.close();
}
rs.close();
pstmt.close();
if (!mflag){
con.commit();
con.close();
}
}
catch (Exception e){
// @@錯誤處理
System.out.println("### Error ExeSQL at execUpdateSQL: " + sql);
CError.buildErr(this, e.toString(), mErrors);
try{
if (pstmt != null){
//由於描述的問題,導致執行的sql錯誤百出,因此pstmt的關閉需要特殊處理
try{
pstmt.close();
}
catch (SQLException ex){
ex.printStackTrace();
}
finally{
try{
System.out.println("Sql's bug is very big: " + sql);
pstmt.close();
}
catch (SQLException ex){}
}
}
if (!mflag){
con.rollback();
con.close();
}
}
catch (SQLException ex){
//在這個地方,有可能會沒有關閉連接
ex.printStackTrace();
return false;
}
return false;
}finally{
try {
if (rs != null) {
rs.close();
}
if (pstmt!=null) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return true;
}