No pains, No gain
          走過、路過、千萬別錯過
          posts - 23,comments - 1,trackbacks - 0
          J2EE程序中使用oracle數(shù)據(jù)庫LOB字段的總結(jié)(elathen)
          ???http://www.souzz.net 2005-10-23 文章出處:博客園
          ?
          ????

          posted on 2005-05-27 09:36 輕松逍遙子

          最近在J2EE的項目中需要使用LOB字段保存文本信息以及圖片和文件,到網(wǎng)上搜拉一下,還不少,仔細看拉一下,但都不是很全有的還有錯誤,經(jīng)過幾天的實踐,把問題都解決拉,順便總結(jié)一下,希望對需要的朋友有點參考

          LOB中我們用的比較多的主要有兩種CLOB和BLOB,我們對兩種類型分別討論

          1.CLOB是字符型LOB,主要存儲文本信息,,最長為4G.,在J2EE程序中,比如網(wǎng)頁的textarea中的字符信息比較長,Varchar2字段類型不能滿足時,我們就得用CLOB數(shù)據(jù)類型,我們這次項目中就碰到這種情況.現(xiàn)在我們先說說如何存取CLOB字段

          現(xiàn)在我要把網(wǎng)頁中的textarea元素的信息保存到數(shù)據(jù)庫的CLOB字段中, 我們都知道textarea中的信息當然不能直接保存成CLOB,我們在后臺得到的是String類型的,不多說拉,我們還是以一個實例講吧!

          先建一個test表,表有2個字段:ID,CONTENTS,其中CONTENTS保存CLOB類型的文本數(shù)據(jù)

          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">

          注冊用戶需遵守:

          尊重會員個人隱私、保障會員隱私安全是CSDN的一項基本政策,CSDN不會公開、編輯或透露會員的注冊資料,除非符合以下情況:
          (1) 根據(jù)中華人民共和國國家安全機構(gòu)、公安部門的要求及根據(jù)相應(yīng)的法律程序要求。
          (2) 維護CSDN的商標所有權(quán)及其它權(quán)益。
          (3) 在緊急情況下竭力維護會員個人、其它社會個體和社會大眾的安全。
          (4) 嚴重違反CSDN有關(guān)規(guī)定。
          CSDN保留結(jié)束會員使用網(wǎng)絡(luò)服務(wù)資格的權(quán)利,并保證結(jié)束會員資格后仍為會員保密所有個人隱私。

          </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”);

          接著我們要做的任務(wù)就是如何把String類型CONTENTS存到數(shù)據(jù)庫中的CLOB類型字段中!

          注意:LOB數(shù)據(jù)不能象其它類型數(shù)據(jù)一樣直接插入(INSERT)。插入前必須先插入一個空的LOB對象,CLOB類型的空對象為EMPTY_CLOB(),BLOB類型的空對象為EMPTY_BLOB()。之后通過SELECT命令查詢得到先前插入的記錄并鎖定,繼而將空對象修改為所要插入的LOB對象。

          //我們先插入一個空的CLOB對象

          public int insertEmptyClob() throws Exception {

          Statement statement = null;

          int intResult = -1;

          try {

          //創(chuàng)建數(shù)據(jù)庫操作語句

          statement = connection.createStatement();

          //定義SQL語句

          String strSQL = “INSET INTO TEST (ID,CONTENTS) VALUES(strID, EMPTY_CLOB())”;

          //執(zhí)行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 {

          //設(shè)置不自動提交

          connection.setAutoCommit(false);

          //創(chuàng)建數(shù)據(jù)庫操作語句

          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();

          //數(shù)據(jù)庫提交

          connection.commit();

          } catch(Exception e) {

          e.printStackTrace();

          }finally{

          if(resultset != null) {

          resultset.close();

          }

          if(statement != null) {

          statement.close();

          }

          }

          }

          OK,我們已經(jīng)把這段文本以CLOB字段的形式保存到數(shù)據(jù)庫中了,在實際應(yīng)用中,如果要保存或修改一條記錄,我們要分2步做,先保存或修改非LOB字段類型的字段,再保存或修改LOB字段!接下來我們來把剛才保存到數(shù)據(jù)庫中的CLOB字段讀到j(luò)sp頁面中去。

          我們在保存的時候,CLOB字段會把上面textarea中的文本按原來的格式一行一行(包括空格)都保存到CLOB字段中,讀取的時候我們只要按照原來格式讀起出來就行了(我這里自己用了一個小處理方法,但如果你有更好的方法請告訴我)。在這里我們把CLOB讀到StringBuffer中,為了保存不同行我在行之間加了個“&”字符來區(qū)分。最后轉(zhuǎn)化成String

          放到VO中,這樣就保證從前臺到后臺,從后臺到前臺的數(shù)據(jù)傳遞的一致性!代碼如下:







          /**

          * 獲取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 {

          //設(shè)定數(shù)據(jù)庫不自動提交

          //connection.setAutoCommit(false);

          //創(chuàng)建數(shù)據(jù)庫操作語句

          stmt = connection.createStatement();

          //獲取結(jié)果集

          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);

          sbResult.append("&");

          strClob = bfClob.readLine();

          }

          }

          //提交事務(wù)

          // connection.commit();

          } catch(Exception e) {

          e.printStackTrace();

          throw e;

          } finally {

          if(rs != null) {

          rs.close();

          }

          if(stmt != null) {

          stmt.close();

          }

          }

          return sbResult.toString();

          }

          到j(luò)sp頁面中,我們從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,主要存儲二進制數(shù)據(jù),最長為4G,在J2EE程序中,一般類似于圖片和文件的保存。當然也有另一種方法,就把圖片和文件保存在硬盤上,數(shù)據(jù)庫中只保存圖片的鏈接地址和文件在服務(wù)器上的路徑。如果遇到文件和圖片比較重要的還是需要保存到數(shù)據(jù)庫中(例如:我們做國土資源項目的時候,好多圖片、文件就很重要,需要保存到數(shù)據(jù)庫中),下面我寫一個保存文件到數(shù)據(jù)庫的Blob字段和從數(shù)據(jù)庫的Blob字段中獲取文件的方法(當然完全應(yīng)用還要做其他工作,這里就不多說了,如果你不清楚的可以問我):

          /**

          * 把上傳的文件保存到數(shù)據(jù)庫的Blob字段中

          * @param strTableName 對應(yīng)的表名稱

          * @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 {

          //得到數(shù)據(jù)庫連接

          con = DBConnector.getConnection();

          //構(gòu)建查詢語句

          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());

          //獲取數(shù)據(jù)庫操作語句

          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對象中寫入數(shù)據(jù) */

          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();

          }

          }

          }



          下面的方法是從數(shù)據(jù)庫中得到上傳的文件的輸入流,把輸入流寫到servlet流中,再從頁面中獲取,servlet就不寫了。

          /**

          * 方法描述:得到數(shù)據(jù)庫上傳的文件數(shù)據(jù)

          *

          * 輸入?yún)?shù): 1:表名(String)

          * 2:字段名(String)

          * 3: Where條件(StringBuffer)

          * 5: 輸出流(ServletOutputStream)

          *

          * 輸出參數(shù):void

          * 編寫人: */

          public static void getdownFile(String strTableName,

          String strColumnName,

          StringBuffer sbSQLWhere,

          ServletOutputStream sos) throws Exception {

          Connection con = null;

          PreparedStatement ps = null;

          ResultSet resultset = null;

          try {

          //得到數(shù)據(jù)庫連接

          con = DBConnector.getConnection();

          StringBuffer sbSQL = new StringBuffer();

          //構(gòu)建查詢語句

          sbSQL.append(" SELECT " + strColumnName + " FROM " + strTableName);

          sbSQL.append(sbSQLWhere);



          System.out.println(" sql value is:"+sbSQLWhere.toString());



          ps = con.prepareStatement(sbSQL.toString());

          //執(zhí)行查詢

          resultset = ps.executeQuery();

          while (resultset.next()) {

          //讀取數(shù)據(jù)流

          InputStream is = resultset.getBinaryStream(strColumnName);



          byte[] buf = new byte[2048];

          while(is.read(buf)!=-1) {

          //把數(shù)據(jù)流按塊寫到servlet的輸出流中

          sos.write(buf);

          }



          }

          } catch (Exception ex) {

          ex.printStackTrace();

          throw ex;

          } finally {

          if (ps != null) {

          ps.close();

          }

          if (resultset != null) {

          resultset.close();

          }

          if (con!=null) {

          con.close();

          }

          }

          }

          圖片的保存和文件的保存一樣,如果不清楚的可以和我聯(lián)系



          后記:

          平時總忙著做項目,閑的時候也很懶,總想把自己實際中的一些問題和解決方法小結(jié)一下,但總沒完成,這是第一次寫,寫的不好或不清楚的地方請包涵,下次改進,也希望大家多提意見,大家一起進步!!!!!!!!!!!

          posted on 2007-01-16 16:14 一縷青煙 閱讀(238) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 巨鹿县| 瓦房店市| 高陵县| 黄大仙区| 大庆市| 余江县| 聂荣县| 平舆县| 和静县| 方城县| 班戈县| 科技| 江城| 玉屏| 沁水县| 承德县| 桦甸市| 临城县| 南乐县| 阿城市| 营山县| 大渡口区| 长乐市| 台安县| 太保市| 西昌市| 镇江市| 微博| 沂源县| 乐亭县| 灵台县| 武平县| 丹凤县| 铜陵市| 芦山县| 米脂县| 廊坊市| 南皮县| 阳城县| 新疆| 金华市|