不依赖驱动更新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;
  }
  ```
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值