数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
通过JDBC操纵Oracle数据库LOB字段的几种情况分析

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

在Oracle中,LOB(Large Object,大型对象)类型的字段现在用得越来越多了。因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种类型的字段,很灵活,适用于数据量非常大的业务领域(如图象、档案等)。而LONG、LONG RAW等类型的字段,虽然存储容量也不小(可达2GB),但由于一个表中只能有一个这样类型的字段的限制,现在已很少使用了。

LOB类型分为BLOB和CLOB两种:BLOB即二进制大型对象(Binary Large Object),适用于存贮非文本的字节流数据(如程序、图象、影音等)。而CLOB,即字符型大型对象(Character Large Object),则与字符集相关,适于存贮文本型的数据(如历史档案、大部头著作等)。

下面以程序实例说明通过JDBC操纵Oracle数据库LOB类型字段的几种情况。

先建立如下两个测试用的数据库表,Power Designer PD模型如下:

建表SQL语句为:

CREATE TABLE TEST_CLOB ( ID NUMBER(3), CLOBCOL CLOB)

CREATE TABLE TEST_BLOB ( ID NUMBER(3), BLOBCOL BLOB)

一、 CLOB对象的存取

1、往数据库中插入一个新的CLOB对象

public static void clobInsert(String infile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 插入一个空的CLOB对象 */

stmt.executeUpdate("INSERT INTO TEST_CLOB VALUES ('111', EMPTY_CLOB())");

/* 查询此CLOB对象并锁定 */

ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");

while (rs.next()) {

/* 取出此CLOB对象 */

oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");

/* 向CLOB对象中写入数据 */

BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());

BufferedReader in = new BufferedReader(new FileReader(infile));

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

in.close();

out.close();

}

/* 正式提交 */

conn.commit();

} catch (Exception ex) {

/* 出错回滚 */

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

2、修改CLOB对象(是在原CLOB对象基础上进行覆盖式的修改)

public static void clobModify(String infile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 查询CLOB对象并锁定 */

ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");

while (rs.next()) {

/* 获取此CLOB对象 */

oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");

/* 进行覆盖式修改 */

BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());

BufferedReader in = new BufferedReader(new FileReader(infile));

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

in.close();

out.close();

}

/* 正式提交 */

conn.commit();

} catch (Exception ex) {

/* 出错回滚 */

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

3、替换CLOB对象(将原CLOB对象清除,换成一个全新的CLOB对象)

public static void clobReplace(String infile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 清空原CLOB对象 */

stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID='111'");

/* 查询CLOB对象并锁定 */

ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");

while (rs.next()) {

/* 获取此CLOB对象 */

oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");

/* 更新数据 */

BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());

BufferedReader in = new BufferedReader(new FileReader(infile));

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

in.close();

out.close();

}

/* 正式提交 */

conn.commit();

} catch (Exception ex) {

/* 出错回滚 */

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

4、CLOB对象读取

public static void clobRead(String outfile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 查询CLOB对象 */

ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_CLOB WHERE ID='111'");

while (rs.next()) {

/* 获取CLOB对象 */

oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");

/* 以字符形式输出 */

BufferedReader in = new BufferedReader(clob.getCharacterStream());

BufferedWriter out = new BufferedWriter(new FileWriter(outfile));

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

out.close();

in.close();

}

} catch (Exception ex) {

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

二、 BLOB对象的存取

1、 向数据库中插入一个新的BLOB对象

public static void blobInsert(String infile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 插入一个空的BLOB对象 */

stmt.executeUpdate("INSERT INTO TEST_BLOB VALUES ('222', EMPTY_BLOB())");

/* 查询此BLOB对象并锁定 */

ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");

while (rs.next()) {

/* 取出此BLOB对象 */

oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");

/* 向BLOB对象中写入数据 */

BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());

BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

in.close();

out.close();

}

/* 正式提交 */

conn.commit();

} catch (Exception ex) {

/* 出错回滚 */

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

2、修改BLOB对象(是在原BLOB对象基础上进行覆盖式的修改)

public static void blobModify(String infile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 查询BLOB对象并锁定 */

ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");

while (rs.next()) {

/* 取出此BLOB对象 */

oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");

/* 向BLOB对象中写入数据 */

BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());

BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

in.close();

out.close();

}

/* 正式提交 */

conn.commit();

} catch (Exception ex) {

/* 出错回滚 */

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

3、替换BLOB对象(将原BLOB对象清除,换成一个全新的BLOB对象)

public static void blobReplace(String infile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 清空原BLOB对象 */

stmt.executeUpdate("UPDATE TEST_BLOB SET BLOBCOL=EMPTY_BLOB() WHERE ID='222'");

/* 查询此BLOB对象并锁定 */

ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");

while (rs.next()) {

/* 取出此BLOB对象 */

oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");

/* 向BLOB对象中写入数据 */

BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());

BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

in.close();

out.close();

}

/* 正式提交 */

conn.commit();

} catch (Exception ex) {

/* 出错回滚 */

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

4、BLOB对象读取

public static void blobRead(String outfile) throws Exception

{

/* 设定不自动提交 */

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

try {

/* 查询BLOB对象 */

ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222'");

while (rs.next()) {

/* 取出此BLOB对象 */

oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");

/* 以二进制形式输出 */

BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outfile));

BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());

int c;

while ((c=in.read())!=-1) {

out.write(c);

}

in.close();

out.close();

}

/* 正式提交 */

conn.commit();

} catch (Exception ex) {

/* 出错回滚 */

conn.rollback();

throw ex;

}

/* 恢复原提交状态 */

conn.setAutoCommit(defaultCommit);

}

观察上述程序对LOB类型字段的存取,我们可以看出,较之其它类型字段,有下面几个显著不同的特点:

一是必须取消自动提交。

存取操作开始前,必须用setAutoCommit(false)取消自动提交。其它类型字段则无此特殊要求。这是因为存取LOB类型字段时,通常要进行多次操作可以完成。不这样的话,Oracle将抛出“读取违反顺序”的错误。

二是插入方式不同。

LOB数据不能象其它类型数据一样直接插入(INSERT)。插入前必须先插入一个空的LOB对象,CLOB类型的空对象为EMPTY_CLOB(),BLOB类型的空对象为EMPTY_BLOB()。之后通过SELECT命令查询得到先前插入的记录并锁定,继而将空对象修改为所要插入的LOB对象。

三是修改方式不同。

其它类型的字段修改时,用UPDATE … SET…命令即可。而LOB类型字段,则只能用SELECT … FOR UPDATE命令将记录查询出来并锁定,然后才能修改。且修改也有两种改法:一是在原数据基础上的修改(即覆盖式修改),执行SELECT … FOR UPDATE后再改数据;二是替换(先将原数据清掉,再修改),先执行UPDATE命令将LOB字段之值设为空的LOB对象,然后进行第一种改法。建议使用替换的方法,以实现与其它字段UPDATE操作后一样的效果。

四是存取时应使用由数据库JDBC驱动程序提供的LOB操作类。

对于Oracle数据库,应使用oracle.sql.CLOB和oracle.sql.BLOB。不使用由数据库JDBC驱动程序提供的LOB类时,程序运行时易于出现“抽象方法调用”的错误,这是因为JDBC所定义的java.sql.Clob与java.sql.Blob接口,其中的一些方法并未在数据库厂家提供的驱动程序中真正实现。

五是存取手段与文件操作相仿。

对于BLOB类型,应用InputStream/OutputStream类,此类不进行编码转换,逐个字节存取。oracle.sql.BLOB类相应提供了getBinaryStream()和getBinaryOutputStream()两个方法,前一个方法用于读取Oracle的BLOB字段,后一个方法用于将数据写入Oracle的BLOB字段。

对于CLOB类型,应用Reader/Writer类,此类进行编码转换。oracle.sql.CLOB类相应提供了getCharacterStream()和getCharacterOutputStream()两个方法,前一个方法用于读取Oracle的CLOB字段,后一个方法用于将数据写入Oracle的CLOB字段。

需要说明的是,为了大幅提高程序执行效率,对BLOB/CLOB字段的读写操作,应该使用缓冲操作类(带Buffered前缀),即:BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter。例程中全部使用了缓冲操作类。

小结:通过JDBC操纵Oracle数据库的LOB字段,不外乎插入、修改、替换、读取四种方式,掌握起来并不难。在实际操作中要注意上面所说的几点,结合阅读例程源程序,用户会很快明白LOB类型字段的使用的,也必将领悟到这种类型字段的妙处!源文件下载>>

 
     
    发布时间:2003-07-02
文章来源:雨亦奇



相关文章

相关软件