不依赖驱动更新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;
    }

原文地址:https://blog.51cto.com/zhaoanan/2409302

时间: 2024-08-25 04:13:59

不依赖驱动更新blob字段的相关文章

Java读取/更新Oracle数据库blob字段

在写java程序过程中,如何读取Oracle数据库表某类型为blob的字段? 以下是我在写程序的时候一种解决方法.核心语句.(传上来做了修改,格式不要学习,养成良好习惯) 详细请参考: 读取序列ID:http://blog.csdn.net/yzsind/article/details/6918506 BLOB相关:http://jslfl.iteye.com/blog/1771949 http://www.linuxidc.com/Linux/2011-08/40218.htm http://

Oracle blob字段的插入和更新

blob字段,其实是用来存储二进制类型的数据的,比如:大文本.文件.图片等信息直接存放到数据库中的一种解决方案 所以,如果对于新插入的记录,存在blob类型的字段,需要在blob字段中先使用EMPTY_BLOB(),让该条记录先保存到数据库中: 然后,使用更新语句的方式,更新blob字段的值,代码如下: //构造更新语句: string strSQL="update  tablename  set Rangecoords=:coords where 查询条件"; //创建oracle参

mysql更新大字段

<input id="btn_sealchange" type="button" value="更改印章" class="btn btn-info" onclick="selectSeal(${seal.sealImageId});"> <input id="sealinfo" name="file" type="file" on

oracle中一些关于blob字段的操作

---恢复内容开始--- 1.在IDE中查看blob字段的内容可以采用: UTL_RAW.CAST_TO_VARCHAR2(blob)的方法,其中blob为表中blob字段的列名.这个方法限定结果不可超过2000字节. 2. 更新blob时,碰到德文乱码问题,最后采用的是在转换为byte[]后,再次转换为new String(ISO-8839-1)就可以

Java实现下载BLOB字段中的文件

概述 web项目的文件下载实现:servlet接收请求,spring工具类访问数据库及简化大字段内容获取. 虽然文章的demo中是以sevlet为平台,想必在spring mvc中也有参考意义. 核心代码 响应设置和输出 1 public void service(ServletRequest request, final ServletResponse response) 2 throws ServletException, IOException { 3 /* 1. 设置响应内容类型 */

由于数据库 Blob字段太多,导致从库进行binlog不能正常进行的处理方法

binlog_format为row格式的时候记录的不是简单的sql,而是实际变更的行,一些大的DML操作,会导致binlog量增加很大,消耗额外的IO.网络资源 可以通过设置binlog_row_image=minimal解决 测试: binlog_row_image默认值是full 对user表进行update 进入binlog里面查看更新记录,binlog日志将所有影响的行都进行了记录 现在将binlog_row_image=minimal 对表中的行进行相同的update操作 再来观察下b

JAVA读取Oracle数据库BLOB字段数据文件并保存到本地文件

******JAVA读取Oracle数据库BLOB字段数据文件并保存到本地文件****** package com.bo.test; import java.io.FileOutputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import

EF更新指定字段...

EF更新指定的字段... 搜来搜去发现没有自己想要的啊... 或许本来就有更好的办法来实现我这个,所以没有人来搞吧... 如果有,请不吝告知..GG.. //要更改UserInfo表中指定的列,比如这个表有15列,如果很多列都要更新,就要判断要更新哪个不要更新哪个.. //现在这样就是传过来多少列,循环更新下就可以了 public string UserInfo_Update_Test(string jsonParames) { jsonParames = "一个json串";//比如

MYSQL BLOB 字段大小以及个数的限制测试。

测试结论 mysql版本 5.1 表类型: innodb, row_format=compact (这是默认的行格式) 插入超过10个blob, blob的数据量很小(<768字节), 插入成功. 插入超过10个blob, blob的数据量很大(>768字节), 插入失败:报 Got error 139 from storage engine. 注意,如果mysql服务器版本是5.1, innodb_file_format选项不存在, 也就无从谈起Barracuda格式. 设置row_form