JDBC CLOB\BLOB操作

这几天遇到个数据迁移大字段的问题一直没有时间解决,今天终于有时间解决这个问题。

场景

SQL Server数据库某张表的数据迁移到Oracle数据库,早期未考虑特殊字段类型的问题,但真正业务应用测试时发现了问题,对应Oracle中该字段内容为空(迁移时忽略了)。需要我们依据主键将SQL Server表中的内容更新到Oracle上来,直接利用JDBC就可以处理此问题。

JDBC处理的一些总结

Oracle JDBC驱动程序有兼容问题,有JDBC3\JDBC4之分

Oracle下对CLOB的操作是字符流的形式,在JDBC4之前插入带有CLOB的数据需要分两步

  1. 使用EMPTY_CLOB(),先插入到数据库这时该字段值为空
  1. 插入完成后单独对CLOB字段进行更新操作

JDBC4之后Oracle11G对这块的处理改善了很多

  1. 使用connection对象创建Clob对象,将值写入该Clob对象
  2. 直接添加到PreparedStatement的parameter即可

SQL Server数据库JDBC

  1. 取TEXT/NTEXT类型字段值,直接通过ResultSet#getString(index)即可
  1. 取BINARY类型则需要通过字节流的方式完成

示例代码

JDBC4.0对CLOB的插入

    /**
     * 测试插入
     * <p>1、注意Oracle的JDBC驱动为ojdbc6.jar
     * @throws SQLException
     */
    public void insertDateNew() throws SQLException {
        String sql = "INSERT INTO ".concat(tableName).concat(" (ID,CONTENT) VALUES(?,?)");
        PreparedStatement pstmt = null;
        try {
            this.conn.setAutoCommit(false);
            pstmt = this.conn.prepareStatement(sql);
            for (int i = 1; i < 50; i++) {
                pstmt.setString(1, String.valueOf(i));
                Clob clob = this.conn.createClob();
                clob.setString(1, "HelloWorld " + i);
                pstmt.setClob(2, clob);
                pstmt.addBatch();
            }
            pstmt.executeBatch();
            this.conn.commit();
        } catch (SQLException e) {
            this.conn.rollback();
            e.printStackTrace();
        } finally {
            this.conn.setAutoCommit(true);
            DBUtils.close(pstmt);
        }
    }

JDBC3.0的插入

    /**
     * 测试插入CLOB
     */
    public void insertData() throws SQLException {
        String sql = "INSERT INTO ".concat(tableName).concat(" (ID,CONTENT) VALUES(?,EMPTY_CLOB())");
        PreparedStatement pstmt = null;
        try {
            this.conn.setAutoCommit(false);
            pstmt = this.conn.prepareStatement(sql);
            for (int i = 1; i < 50; i++) {
                pstmt.setString(1, String.valueOf(i));
                pstmt.addBatch();
            }
            pstmt.executeBatch();
            this.updateInsertCLOB();
            this.conn.commit();
        } catch (SQLException e) {
            this.conn.rollback();
            e.printStackTrace();
        } finally {
            this.conn.setAutoCommit(true);
            DBUtils.close(pstmt);
        }
    }

    /**
     * 支持未实现JDBC4的情况
     * @param pstmt {@link PreparedStatement}
     * @throws SQLException
     */
    private void updateInsertCLOB() throws SQLException {
        String sql = "SELECT ID,CONTENT FROM ".concat(tableName);
        PreparedStatement pstmt = null;
        ResultSet resultSet = null;
        try {
            pstmt = this.conn.prepareStatement(sql);
            resultSet = pstmt.executeQuery(sql);
            while (resultSet.next()) {
                Clob clobInst = resultSet.getClob(2);
                Writer writerInst = clobInst.setCharacterStream(1);
                writerInst.write("HelloWorld " + resultSet.getString(1));
                writerInst.close();
            }
        } catch (IOException e) {
            throw new SQLException(e.getCause());
        } finally {
            DBUtils.close(pstmt);
        }
    }

字节/字符流类型处理

    /**
     * 测试查询
     * <p>
     * 1、TEXT类型直接getString即可
     * <p>
     * 2、主要是BINARY类型的处理
     * @throws SQLException
     */
    public void queryDate() throws SQLException {
        String qrySql = "SELECT * FROM BLOB_TABLE A WHERE A.ID=?";
        PreparedStatement pstmt = null;
        try {
            pstmt = this.conn.prepareStatement(qrySql);
            pstmt.setString(1, "1");
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()) {
                InputStream ins = rs.getBinaryStream("PHOTO");
                restoreInputStream(ins);
                ins.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            DBUtils.close(pstmt);
        }
    }

    /**
     * 转储输入流
     * @param ins {@link InputStream}
     * @throws IOException IOException
     */
    private void restoreInputStream(InputStream ins) {
        BufferedOutputStream bosInst = null;
        byte[] buff = new byte[1024 * 1024];
        try {
            bosInst = new BufferedOutputStream(new FileOutputStream("C:\\ttt.zip"));
            int flag = -1;
            while ((flag = ins.read(buff)) != -1) {
                bosInst.write(buff, 0, flag);
            }
            bosInst.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bosInst != null) {
                try {
                    bosInst.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值