您的位置:首页 > 其它

JDBC CLOB\BLOB操作

2012-08-30 20:13 363 查看
这几天遇到个数据迁移大字段的问题一直没有时间解决,今天终于有时间解决这个问题。

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

JDBC处理的一些总结
Oracle JDBC驱动程序有兼容问题,有JDBC3\JDBC4之分

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

使用EMPTY_CLOB(),先插入到数据库这时该字段值为空
插入完成后单独对CLOB字段进行更新操作
JDBC4之后Oracle11G对这块的处理改善了很多

使用connection对象创建Clob对象,将值写入该Clob对象
直接添加到PreparedStatement的parameter即可
SQL Server数据库JDBC

取TEXT/NTEXT类型字段值,直接通过ResultSet#getString(index)即可
取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();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: