不依賴驅動更新blob字段

不依賴驅動更新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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章