LOB中咱們用的比較多的主要有兩種CLOB和BLOB,咱們對兩種類型分別討論html
1.CLOB是字符型LOB,主要存儲文本信息,最長爲4G.,在J2EE程序中,好比網頁的textarea中的字符信息比較長,Varchar2字段類型不能知足時,咱們就得用CLOB數據類型,咱們此次項目中就碰到這種狀況.如今咱們先說說如何存取CLOB字段java
如今我要把網頁中的textarea元素的信息保存到數據庫的CLOB字段中, 咱們都知道textarea中的信息固然不能直接保存成CLOB,咱們在後臺獲得的是String類型的,很少說拉,咱們仍是以一個實例講吧!sql
先建一個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類型的對象oracle
String strID = request.getParameter("ID");
String strContents = request.getParameter("CONTENTS");app
接着咱們要作的任務就是如何把String類型CONTENTS存到數據庫中的CLOB類型字段中!jsp
注意:LOB數據不能象其它類型數據同樣直接插入(INSERT)。插入前必須先插入一個空的LOB對象,CLOB類型的空對象爲EMPTY_CLOB (),BLOB類型的空對象爲EMPTY_BLOB()。以後經過SELECT命令查詢獲得先前插入的記錄並鎖定,繼而將空對象修改成所要插入的LOB對象。post
//
咱們先插入一個空的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就不寫了。