Java程序中使用oracle数据库LOB字段的总结

 

LOB中我们用的比较多的主要有两种CLOB和BLOB,我们对两种类型分别讨论

1.CLOB是字符型LOB,主要存储文本信息,最长为4G.,在J2EE程序中,比如网页的textarea中的字符信息比较长,Varchar2字段类型不能满足时,我们就得用CLOB数据类型,我们这次项目中就碰到这种情况.现在我们先说说如何存取CLOB字段

现在我要把网页中的textarea元素的信息保存到数据库的CLOB字段中, 我们都知道textarea中的信息当然不能直接保存成CLOB,我们在后台得到的是String类型的,不多说拉,我们还是以一个实例讲吧!

先建一个test表,表有2个字段:ID,CONTENTS,其中CONTENTS保存CLOB类型的文本数据

 

create   table  TEST
(
ID 
VARCHAR2 ( 18 not   null ,
CONTENTS CLOB,
)

 

接着我们编写一个测试用的jsp文件ClobTest.jsp,代码如下

 

<% ... @ page language="java" contentType="text/html; charset=gb2312"  %>
< html >
< head >
< meta  http-equiv ="Content-Type"  content ="text/html; charset=gb2312" >
< title > Clob对象的存取测试 </ title >
</ head >

< body >
< form  name ="test"  method ="post"  action ="clobTest.action" >
< table  width ="80%"  height ="88"  border ="0"  align ="center"  cellpadding ="0"  cellspacing ="0" >
< tr >
< td  height ="30"  align ="center" > 输入ID号 < input  type ="text"  name ="ID" >
</ tr >
< tr >
< td  align ="center" >
< textarea  rows ="28"  cols ="68"  name ="CONTENTS" >   </ textarea >
</ td >
</ tr >
< tr >
< td  align ="center" >
< input  type ="submit"  name ="Submit"  value ="提交" >
</ td >
</ tr >
</ table >
</ form >
</ body >
</ html >

 

点击”提交”按钮,我们在后台的到的是2个String类型的对象

  String strID = request.getParameter("ID");
  String strContents = request.getParameter("CONTENTS");

接着我们要做的任务就是如何把String类型CONTENTS存到数据库中的CLOB类型字段中!

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

 

// 我们先插入一个空的CLOB对象
public   int  insertEmptyClob()  throws  Exception  ... {
Statement statement 
= null;
int intResult = -1;
try ...{
//创建数据库操作语句
statement = connection.createStatement();
//定义SQL语句
String strSQL = “INSET INTO TEST (ID,CONTENTS) VALUES(strID, EMPTY_CLOB())”;
//执行SQL语句
intResult = statement.executeUpdate(strSQL);
System.out.println(
" intResult valus is"+intResult);
return intResult;
}
 catch(Exception e) ...{
e.printStackTrace();
return -1;
}
 finally ...{
if (statement != null...{
statement.close();
}

}

}


// 把strCONTENT插入CLOB字段

public   void  insertClob()  throws  Exception  ... {
Statement statement 
= null;
ResultSet resultset 
= null;
try ...{
//设置不自动提交
connection.setAutoCommit(false);
//创建数据库操作语句
statement = connection.createStatement();
//定义SQL语句
String strSQL = “SELECT CONTENTS FROM TEST WHERE ID=strID"
resultset = statement.executeQuery(strSQL);
oracle.sql.CLOB contents 
= null;
while(resultset.next()) ...{
//取出CLOB对象
contents = (oracle.sql.CLOB)resultset.getClob("CONTENTS");
}

Writer out 
= contents.getCharacterOutputStream();
out.write(strContents);
out.flush();
out.close();
//数据库提交
connection.commit();
}
 catch(Exception e) ...{
e.printStackTrace();
}
finally...{
if(resultset != null...{
resultset.close();
}

if(statement != null...{
statement.close();
}

}

}


 

OK,我们已经把这段文本以CLOB字段的形式保存到数据库中了,在实际应用中,如果要保存或修改一条记录,我们要分2步做,先保存或修改非LOB字段类型的字段,再保存或修改LOB字段!接下来我们来把刚才保存到数据库中的CLOB字段读到jsp页面中去。

我们在保存的时候,CLOB字段会把上面textarea中的文本按原来的格式一行一行(包括空格)都保存到CLOB字段中,读取的时候我们只要按照原来格式读起出来就行了(我这里自己用了一个小处理方法,但如果你有更好的方法请告诉我)。在这里我们把CLOB读到StringBuffer中,为了保存不同行我在行之间加了个“&”字符来区分。最后转化成String

放到VO中,这样就保证从前台到后台,从后台到前台的数据传递的一致性!代码如下:

/** */ /**
* 获取CLOB文本对象
@param  sbSQL
@return
@throws  java.lang.Exception
*/


public  String selectIncludeClob(StringBuffer sbSQL)  throws  Exception  ... {
Statement stmt 
= null;
ResultSet rs 
= null;
StringBuffer sbResult 
= new StringBuffer();
try ...{
//设定数据库不自动提交
//connection.setAutoCommit(false);
//创建数据库操作语句
stmt = connection.createStatement();
//获取结果集
rs = stmt.executeQuery(sbSQL.toString());

while(rs.next()) ...{
CLOB clob 
= (CLOB)rs.getClob("CONTENTS");
Reader isClob 
= clob.getCharacterStream();
BufferedReader bfClob 
= new BufferedReader(isClob);
String strClob 
= bfClob.readLine();
while(strClob != null...{
sbResult.append(strClob);
bResult.append(
"&");
strClob 
= bfClob.readLine();
}

}

//提交事务
// connection.commit();
}
 catch(Exception e) ...{
e.printStackTrace();
throw e;
}
 finally ...{
if(rs != null...{
rs.close();
}

if(stmt != null...{
stmt.close();
}

}

return sbResult.toString();
}


 

到jsp页面中,我们从VO中获取改文本信息。

< textarea  rows ="42"  cols ="68"  name ="CONTENTS"  style ="border-style: solid; border-color: #FFFFFF; font-family:仿宋_GB2312; font-size:14pt; line-height:200%; margin-top:8; margin-bottom:6"   >
<% ...
String content = vo.getContent();
String[] contentArray = content.split("&");
for(int i=0;i<contentArray.length;i++) {
String s= contentArray[i];
out.println(s);
}
%>
</ textarea >

 

这样我们就保证什么格式保存就以什么格式显示。

2.BLOB字段,二进制LOB,主要存储二进制数据,最长为4G,在J2EE程序中,一般类似于图片和文件的保存。当然也有另一种方法,就把图片和文件保存在硬盘上,数据库中只保存图片的链接地址和文件在服务器上的路径。如果遇到文件和图片比较重要的还是需要保存到数据库中(例如:我们做国土资源项目的时候,好多图片、文件就很重要,需要保存到数据库中),下面我写一个保存文件到数据库的Blob字段和从数据库的Blob字段中获取文件的方法

 

/** */ /**
* 把上传的文件保存到数据库的Blob字段中
@param  strTableName 对应的表名称
@param strColumnName 表中保存文件的Blob字段名称
@param inputStream 输入的文件流
@param sbSQLWhere where条件
@throws java.lang.Exception
*/

public   static   void  fileUpload(String strTableName,
String strColumnName,
InputStream inputStream,
StringBuffer sbSQLWhere)
throws  Exception  ... {
Connection con 
= null;
ResultSet resultset 
= null;
Statement stmt 
= null;
try ...{
//得到数据库连接
con = DBConnector.getConnection();
//构建查询语句
StringBuffer sbSQL = new StringBuffer();
sbSQL.append(
" UPDATE ");
sbSQL.append(strTableName);
sbSQL.append(
" SET ");
sbSQL.append(strColumnName);
sbSQL.append(
"=EMPTY_BLOB() ");
sbSQL.append(sbSQLWhere);
System.out.println(
" update sql value is*******"+sbSQL.toString());
//获取数据库操作语句
stmt=con.createStatement();
//插入空的blob对象
stmt.executeUpdate(sbSQL.toString());
con.setAutoCommit(
false);
StringBuffer sbSQLBlob 
= new StringBuffer();
sbSQLBlob.append(
" SELECT ");
sbSQLBlob.append(strColumnName);
sbSQLBlob.append(
" FROM ");
sbSQLBlob.append(strTableName);
sbSQLBlob.append(sbSQLWhere);
sbSQLBlob.append(
" FOR UPDATE");
System.out.println(
" select sql value is*********"+sbSQL.toString());
resultset 
=stmt.executeQuery(sbSQLBlob.toString());
while (resultset.next()) ...{
/**//* 取出此BLOB对象 */
oracle.sql.BLOB blob 
= (oracle.sql.BLOB)resultset.getBlob("BODY");
/**//* 向BLOB对象中写入数据 */
BufferedOutputStream out 
= new BufferedOutputStream(blob.getBinaryOutputStream());
BufferedInputStream in 
= new BufferedInputStream(inputStream);
int c;
while ((c=in.read())!=-1...{
out.write(c);
}

in.close();
out.close();
}

con.setAutoCommit(
false);
con.commit();
}
 catch (Exception ex) ...{
ex.printStackTrace();
throw ex;
}
 finally ...{
if (stmt != null...{
stmt.close();
}

If (resultset 
!= null...{
resultset.close();
}

if (con!=null...{
con.close();
}

}

}

 

下面的方法是从数据库中得到上传的文件的输入流,把输入流写到servlet流中,再从页面中获取,servlet就不写了。

你可能感兴趣的:(Java程序中使用oracle数据库LOB字段的总结)