关于使用JDBC 2.0操作Oracle 9i数据库的Clob字段的问题 为什么使用ResultSet.CONCUR_READ_ONLY标志呢?这样只能读取结果集,写数据肯定不成功的。应该是使用可写的结果集才对。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 Oracle JDBC驱动处理clob似乎有问题,用jtds驱动包可解决此问题 ResultSet.CONCUR_READ_ONLY是针对返回的结果集的吧,我的是update语句,不是对返回结果集进行操作 改用JDBC 3.0驱动也能解决问题,但是现在没办法改变环境,只有去遵守 package jdbc.day4 ;import java.sql.*;import java.io.*;/* *用于演示Blob字段的插入与查询。 */public class BlobSample{ /* *向mp3_table中插入一条数据 *name : 歌曲的名称 *path : 歌曲的路径 */ public void insertBlob( String name , String path ) { Connection conn = null; PreparedStatement pstm = null ; ResultSet rs = null; try{ //获得一个数据库连接, Class.forName( "oracle.jdbc.driver.OracleDriver" ); conn = DriverManager.getConnection( "jdbc:oracle:thin:@192.168.1.100:1521:sid", "user", "pwd" ) ; // *在使用Blob时,必须设置AutoCommit属性为false .* conn.setAutoCommit( false ); //1 , 向表中插入一个空的Blob字段。 //"empyt_blob()" 是Oracle提供的一个SQL函数,用于创建一个空的Blob对象。 pstm = conn.prepareStatement( "insert into mp3_table( name, mp3 ) values( ? , empty_blob() )" ) ; pstm.setString( 1 , name ) ; pstm.executeUpdate(); //*此处不能提交事务,因为mp3的内容还没有插入到数据库中 * System.out.println( "insert empty blob successful ......" ); //2,获得blog字段的输出流。 //2.1 将刚刚插入的空字段查询出来。 pstm.close(); //在查询时必须使用for update子句,确保数据的线程安全。 pstm = conn.prepareStatement( "select mp3 from mp3_table where name = ? for update" ); pstm.setString( 1 , name ) ; rs = pstm.executeQuery(); if( rs.next() ){ //在使用Blob时要强制转化成oracle.sql.BLOB //该类由JDBC driver提供( classes12.jar ) ; Blob b = rs.getBlob( 1 ); oracle.sql.BLOB ob = (oracle.sql.BLOB ) b ; OutputStream os = ob.getBinaryOutputStream(); System.out.println( "get binary outputStream successful ...." ); //通过输出流将数据写入数据库。 InputStream is = new FileInputStream( path ) ; byte buffer[] = new byte[ 4096 ] ; int len = 0 ; while( true ){ len = is.read( buffer ) ; if( len == -1 ) break ; os.write( buffer , 0 , len ) ; System.out.println( len + " bytes writed ." ); } //必须在Commit之前关闭输入输出流。 is.close(); os.close(); //提交事务 conn.commit(); System.out.println( "insert " + name + " successful ... " ); } }catch(Exception e ){ e.printStackTrace(); if( conn != null ) try{ conn.rollback(); } catch( Exception e1 ){} }finally{ if( rs != null ) try{ rs.close() ; }catch( Exception e ) {} if( pstm != null ) try{ pstm.close(); }catch( Exception e ){} if( conn != null ) try{ conn.close(); } catch( Exception e ){} } } /* * 这个方法的功能是在mp3_table中根据名称查询mp3, * 并且把查询结果保存在磁盘的文件中。 *name : 用来制定mp3的名称。 *path : 用来制定保存mp3的文件路径。 */ public void queryBlob( String name , String path ) { Connection conn = null; PreparedStatement pstm = null; ResultSet rs = null; try{ // 连接数据库 Class.forName( "oracle.jdbc.driver.OracleDriver" ); conn = DriverManager.getConnection( "jdbc:oracle:thin:@192.168.1.100:1521:tarena" , "sd0605" , "sd0605" ); conn.setAutoCommit( false ) ; //执行查询语句 pstm = conn.prepareStatement( "select mp3 from mp3_table where name=? for update" ); pstm.setString( 1 , name ) ; rs = pstm.executeQuery(); //获得执行结果。 if( rs.next() ){ Blob b = rs.getBlob( 1 ) ; //获得输入流,此处不需要做强制类型转化 InputStream is = b.getBinaryStream(); OutputStream os = new FileOutputStream( path ); byte buffer[] = new byte[ 4096 ] ; int len = 0 ; while( true ){ len = is.read( buffer ) ; if( len == -1 ) break ; os.write( buffer , 0 , len ) ; System.out.println( len + " bytes read" ); } //在提交事务之前关闭输入,输出流 。 is.close(); os.close(); //提交事务 conn.commit(); } }catch(Exception e ){ e.printStackTrace(); //如果在执行过程中出现异常,回滚数据库操作。 if( conn != null ) try{ conn.rollback(); }catch( Exception e1 ){} }finally{ if( rs != null ) try{ rs.close(); }catch(Exception e ){} if( pstm != null ) try{ pstm.close(); }catch( Exception e ){} if( conn != null ) try{ conn.close(); }catch( Exception e ) {} } } public static void main( String args[] ) { BlobSample sample = new BlobSample(); //sample.insertBlob( "dc.mp3" , "d:/dc.mp3" ); sample.queryBlob( "dc.mp3" , "d:/copy.mp3" ); }} 楼上的这种方法已经试过,由于数据库连接是从WebLogic的连接池中获得的,BEA在上面做了手脚,容易出现类型转换异常。问题自己解决了,使用了比较偏激的方法,继续听取各高手的意见 weblogic.jdbc.rmi.SerialOracleClob tempClob = (weblogic.jdbc.rmi.SerialOracleClob) clob; weblogic.jdbc.rmi.internal.OracleTClobImpl tempClobImpl = (weblogic.jdbc.rmi.internal.OracleTClobImpl) tempClob .getTheRealClob(); CLOB oClob = (CLOB) tempClobImpl.getTheRealClob(); CLOB oClob = (CLOB) clob; Writer writer = oClob.getCharacterOutputStream(); writer.write("Begin" + clobValue + "End"); writer.flush(); writer.close();最终使用了这种方式,可能对容器以及连接池的驱动类型等具有极强的依赖 《急》如果设置IReport的英文字体 Tomcat session数量能统计吗? Spring 运行时动态加载修改过的 配置文件。 急!!!一小问题就是没能解决 你没见过的java 抛IO异常 求解决 Struts2上传文件问题 求助: jdbc 如何在oralce中存放大文本 log4j输出位置 关于xml传输中,附件的问题。 【回归、重金悬赏】关于struts2 的标签使用 动态form的问题 关于struts中tiles的用法
import java.sql.*;
import java.io.*;
/*
*用于演示Blob字段的插入与查询。
*/
public class BlobSample{
/*
*向mp3_table中插入一条数据
*name : 歌曲的名称
*path : 歌曲的路径
*/
public void insertBlob( String name , String path ) {
Connection conn = null;
PreparedStatement pstm = null ;
ResultSet rs = null;
try{
//获得一个数据库连接,
Class.forName( "oracle.jdbc.driver.OracleDriver" );
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.1.100:1521:sid",
"user", "pwd" ) ;
// *在使用Blob时,必须设置AutoCommit属性为false .*
conn.setAutoCommit( false );
//1 , 向表中插入一个空的Blob字段。
//"empyt_blob()" 是Oracle提供的一个SQL函数,用于创建一个空的Blob对象。
pstm = conn.prepareStatement(
"insert into mp3_table( name, mp3 ) values( ? , empty_blob() )" ) ;
pstm.setString( 1 , name ) ;
pstm.executeUpdate();
//*此处不能提交事务,因为mp3的内容还没有插入到数据库中 *
System.out.println( "insert empty blob successful ......" );
//2,获得blog字段的输出流。
//2.1 将刚刚插入的空字段查询出来。
pstm.close();
//在查询时必须使用for update子句,确保数据的线程安全。
pstm = conn.prepareStatement(
"select mp3 from mp3_table where name = ? for update" );
pstm.setString( 1 , name ) ;
rs = pstm.executeQuery();
if( rs.next() ){
//在使用Blob时要强制转化成oracle.sql.BLOB
//该类由JDBC driver提供( classes12.jar ) ;
Blob b = rs.getBlob( 1 );
oracle.sql.BLOB ob = (oracle.sql.BLOB ) b ;
OutputStream os = ob.getBinaryOutputStream();
System.out.println( "get binary outputStream successful ...." );
//通过输出流将数据写入数据库。
InputStream is = new FileInputStream( path ) ;
byte buffer[] = new byte[ 4096 ] ;
int len = 0 ;
while( true ){
len = is.read( buffer ) ;
if( len == -1 ) break ;
os.write( buffer , 0 , len ) ;
System.out.println( len + " bytes writed ." );
}
//必须在Commit之前关闭输入输出流。
is.close();
os.close();
//提交事务
conn.commit();
System.out.println( "insert " + name + " successful ... " );
}
}catch(Exception e ){
e.printStackTrace();
if( conn != null ) try{ conn.rollback(); } catch( Exception e1 ){}
}finally{
if( rs != null ) try{ rs.close() ; }catch( Exception e ) {}
if( pstm != null ) try{ pstm.close(); }catch( Exception e ){}
if( conn != null ) try{ conn.close(); } catch( Exception e ){}
}
}
/*
* 这个方法的功能是在mp3_table中根据名称查询mp3,
* 并且把查询结果保存在磁盘的文件中。
*name : 用来制定mp3的名称。
*path : 用来制定保存mp3的文件路径。
*/
public void queryBlob( String name , String path ) {
Connection conn = null;
PreparedStatement pstm = null;
ResultSet rs = null;
try{
// 连接数据库
Class.forName( "oracle.jdbc.driver.OracleDriver" );
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.1.100:1521:tarena" ,
"sd0605" , "sd0605" );
conn.setAutoCommit( false ) ;
//执行查询语句
pstm = conn.prepareStatement( "select mp3 from mp3_table where name=? for update" );
pstm.setString( 1 , name ) ;
rs = pstm.executeQuery();
//获得执行结果。
if( rs.next() ){
Blob b = rs.getBlob( 1 ) ;
//获得输入流,此处不需要做强制类型转化
InputStream is = b.getBinaryStream();
OutputStream os = new FileOutputStream( path );
byte buffer[] = new byte[ 4096 ] ;
int len = 0 ;
while( true ){
len = is.read( buffer ) ;
if( len == -1 ) break ;
os.write( buffer , 0 , len ) ;
System.out.println( len + " bytes read" );
}
//在提交事务之前关闭输入,输出流 。
is.close();
os.close();
//提交事务
conn.commit();
}
}catch(Exception e ){
e.printStackTrace();
//如果在执行过程中出现异常,回滚数据库操作。
if( conn != null ) try{ conn.rollback(); }catch( Exception e1 ){}
}finally{
if( rs != null ) try{ rs.close(); }catch(Exception e ){}
if( pstm != null ) try{ pstm.close(); }catch( Exception e ){}
if( conn != null ) try{ conn.close(); }catch( Exception e ) {}
}
}
public static void main( String args[] ) {
BlobSample sample = new BlobSample();
//sample.insertBlob( "dc.mp3" , "d:/dc.mp3" );
sample.queryBlob( "dc.mp3" , "d:/copy.mp3" );
}
}
weblogic.jdbc.rmi.internal.OracleTClobImpl tempClobImpl = (weblogic.jdbc.rmi.internal.OracleTClobImpl) tempClob
.getTheRealClob();
CLOB oClob = (CLOB) tempClobImpl.getTheRealClob(); CLOB oClob = (CLOB) clob;
Writer writer = oClob.getCharacterOutputStream();
writer.write("Begin" + clobValue + "End");
writer.flush();
writer.close();最终使用了这种方式,可能对容器以及连接池的驱动类型等具有极强的依赖