在Oracle中,LOB(Large Object,大型對象)類型的字段如今用得愈來愈多了。由於這種類型的字段,容量大(最多能容納4GB的數據),且一個表中能夠有多個這種類型的字段,很靈活,適用於數據 量很是大的業務領域(如圖象、檔案等)。java
LOB類型分爲BLOB和CLOB兩種:BLOB即二進制大型對象(Binary Large Object),適用於存貯非文本的字節流數據(如程序、圖象、影音等)。而CLOB,即字符型大型對象(Character Large Object),則與字符集相關,適於存貯文本型的數據(如歷史檔案、大部頭著做等)。sql
建表SQL語句爲:數據庫
1 CREATE TABLE TEST_CLOB ( ID NUMBER(3), CLOBCOL CLOB) 2 3 CREATE TABLE TEST_BLOB ( ID NUMBER(3), BLOBCOL BLOB)
1 oracleDb_Driver=oracle.jdbc.driver.OracleDriver 2 oracleDb_Url=jdbc:oracle:thin:@localhost:1521:GACL 3 oracleDb_UserName=GACL_XDP 4 oracleDb_Password=P
1 package me.gacl.utils; 2 3 import java.io.InputStream; 4 import java.sql.Connection; 5 import java.sql.DriverManager; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.Properties; 10 11 public class JdbcUtils { 12 13 private static String oracleDb_Driver = null; 14 private static String oracleDb_Url = null; 15 private static String oracleDb_UserName = null; 16 private static String oracleDb_Password = null; 17 18 static{ 19 try{ 20 //讀取db.properties文件中的數據庫鏈接信息 21 InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"); 22 Properties prop = new Properties(); 23 prop.load(in); 24 25 //獲取數據庫鏈接驅動 26 oracleDb_Driver = prop.getProperty("oracleDb_Driver"); 27 //獲取數據庫鏈接URL地址 28 oracleDb_Url = prop.getProperty("oracleDb_Url"); 29 //獲取數據庫鏈接用戶名 30 oracleDb_UserName = prop.getProperty("oracleDb_UserName"); 31 //獲取數據庫鏈接密碼 32 oracleDb_Password = prop.getProperty("oracleDb_Password"); 33 34 //加載數據庫驅動 35 Class.forName(oracleDb_Driver); 36 37 }catch (Exception e) { 38 throw new ExceptionInInitializerError(e); 39 } 40 } 41 42 /** 43 * @Method: getOracleConnection 44 * @Description: 獲取Oracle數據庫鏈接對象 45 * @Anthor:孤傲蒼狼 46 * 47 * @return Connection數據庫鏈接對象 48 * @throws SQLException 49 */ 50 public static Connection getOracleConnection() throws SQLException{ 51 return DriverManager.getConnection(oracleDb_Url, oracleDb_UserName,oracleDb_Password); 52 } 53 54 /** 55 * @Method: release 56 * @Description: 釋放資源, 57 * 要釋放的資源包括Connection數據庫鏈接對象,負責執行SQL命令的Statement對象,存儲查詢結果的ResultSet對象 58 * @Anthor:孤傲蒼狼 59 * 60 * @param conn 61 * @param st 62 * @param rs 63 */ 64 public static void release(Connection conn,Statement st,ResultSet rs){ 65 if(rs!=null){ 66 try{ 67 //關閉存儲查詢結果的ResultSet對象 68 rs.close(); 69 }catch (Exception e) { 70 e.printStackTrace(); 71 } 72 rs = null; 73 } 74 if(st!=null){ 75 try{ 76 //關閉負責執行SQL命令的Statement對象 77 st.close(); 78 }catch (Exception e) { 79 e.printStackTrace(); 80 } 81 } 82 83 if(conn!=null){ 84 try{ 85 //關閉Connection數據庫鏈接對象 86 conn.close(); 87 }catch (Exception e) { 88 e.printStackTrace(); 89 } 90 } 91 } 92 }
1 package me.gacl.demo; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileReader; 6 import java.io.FileWriter; 7 import java.sql.Connection; 8 import java.sql.PreparedStatement; 9 import java.sql.ResultSet; 10 import org.junit.Test; 11 import me.gacl.utils.JdbcUtils; 12 13 /** 14 * @ClassName: JdbcOperaOracleClob 15 * @Description:Oracle中字符型大型對象(Character Large Object)數據處理 16 * @author: 孤傲蒼狼 17 * @date: 2014-10-7 下午3:53:19 18 * 19 */ 20 public class JdbcOperaOracleClob { 21 22 /** 23 CREATE TABLE TEST_CLOB ( ID NUMBER(3), CLOBCOL CLOB) 24 */ 25 /** 26 * @Method: clobInsert 27 * @Description:往數據庫中插入一個新的CLOB對象 28 * @Anthor:孤傲蒼狼 29 * 30 * @throws Exception 31 */ 32 @Test 33 public void clobInsert() throws Exception { 34 Connection conn = null; 35 PreparedStatement stmt = null; 36 ResultSet rs = null; 37 conn = JdbcUtils.getOracleConnection(); 38 boolean defaultCommit = conn.getAutoCommit(); 39 /*開啓事務,設定不自動提交 */ 40 conn.setAutoCommit(false); 41 try { 42 /* 插入一個空的CLOB對象 */ 43 String sql = "INSERT INTO TEST_CLOB VALUES (?, EMPTY_CLOB())"; 44 stmt = conn.prepareStatement(sql); 45 stmt.setInt(1, 1); 46 stmt.executeUpdate(); 47 /* 查詢此CLOB對象並鎖定 */ 48 sql = "SELECT CLOBCOL FROM TEST_CLOB WHERE ID=? FOR UPDATE"; 49 stmt = conn.prepareStatement(sql); 50 stmt.setInt(1, 1); 51 rs = stmt.executeQuery(); 52 if (rs.next()) { 53 /* 取出此CLOB對象 */ 54 oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL"); 55 /* 向CLOB對象中寫入數據 */ 56 BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream()); 57 //這種方式獲取的路徑,其中的空格會被使用「%20」代替 58 String path = JdbcOperaClob.class.getClassLoader().getResource("data.txt").getPath(); 59 //將「%20」替換回空格 60 path = path.replaceAll("%20", " "); 61 BufferedReader in = new BufferedReader(new FileReader(path)); 62 int c; 63 while ((c = in.read()) != -1) { 64 out.write(c); 65 } 66 in.close(); 67 out.close(); 68 } 69 /* 正式提交 */ 70 conn.commit(); 71 System.out.println("插入成功"); 72 } catch (Exception ex) { 73 /* 出錯回滾 */ 74 conn.rollback(); 75 throw ex; 76 }finally{ 77 /* 恢復原提交狀態 */ 78 conn.setAutoCommit(defaultCommit); 79 JdbcUtils.release(conn,stmt,rs); 80 } 81 82 } 83 84 /** 85 * @Method: clobRead 86 * @Description: CLOB對象讀取 87 * @Anthor:孤傲蒼狼 88 * 89 * @throws Exception 90 */ 91 @Test 92 public void clobRead() throws Exception { 93 Connection conn = null; 94 PreparedStatement stmt = null; 95 ResultSet rs = null; 96 conn = JdbcUtils.getOracleConnection(); 97 boolean defaultCommit = conn.getAutoCommit(); 98 conn.setAutoCommit(false); 99 try { 100 /* 查詢CLOB對象 */ 101 String sql = "SELECT * FROM TEST_CLOB WHERE ID=?"; 102 stmt = conn.prepareStatement(sql); 103 stmt.setInt(1, 1); 104 rs = stmt.executeQuery(); 105 if (rs.next()) { 106 /* 獲取CLOB對象 */ 107 oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL"); 108 /* 以字符形式輸出 */ 109 BufferedReader in = new BufferedReader(clob.getCharacterStream()); 110 BufferedWriter out = new BufferedWriter(new FileWriter("D:\\2.txt")); 111 int c; 112 while ((c = in.read()) != -1) { 113 out.write(c); 114 } 115 out.close(); 116 in.close(); 117 } 118 } catch (Exception ex) { 119 conn.rollback(); 120 throw ex; 121 }finally{ 122 /* 恢復原提交狀態 */ 123 conn.setAutoCommit(defaultCommit); 124 JdbcUtils.release(conn,stmt,rs); 125 } 126 } 127 128 /** 129 * @Method: clobModify 130 * @Description:修改CLOB對象(是在原CLOB對象基礎上進行覆蓋式的修改) 131 * @Anthor:孤傲蒼狼 132 * 133 * @throws Exception 134 */ 135 @Test 136 public void clobModify() throws Exception { 137 Connection conn = null; 138 PreparedStatement stmt = null; 139 ResultSet rs = null; 140 conn = JdbcUtils.getOracleConnection(); 141 boolean defaultCommit = conn.getAutoCommit(); 142 // 開啓事務 143 conn.setAutoCommit(false); 144 try { 145 /* 查詢CLOB對象並鎖定 */ 146 String sql = "SELECT CLOBCOL FROM TEST_CLOB WHERE ID=? FOR UPDATE"; 147 stmt = conn.prepareStatement(sql); 148 stmt.setInt(1, 1); 149 rs = stmt.executeQuery(); 150 if (rs.next()) { 151 /* 獲取此CLOB對象 */ 152 oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL"); 153 /* 進行覆蓋式修改 */ 154 BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream()); 155 // 這種方式獲取的路徑,其中的空格會被使用「%20」代替 156 String path = JdbcOperaClob.class.getClassLoader().getResource("data2.txt").getPath(); 157 // 將「%20」替換回空格 158 path = path.replaceAll("%20", " "); 159 BufferedReader in = new BufferedReader(new FileReader(path)); 160 int c; 161 while ((c = in.read()) != -1) { 162 out.write(c); 163 } 164 in.close(); 165 out.close(); 166 } 167 /*提交事務 */ 168 conn.commit(); 169 } catch (Exception ex) { 170 /*出錯回滾事務 */ 171 conn.rollback(); 172 throw ex; 173 }finally{ 174 /*恢復原提交狀態 */ 175 conn.setAutoCommit(defaultCommit); 176 JdbcUtils.release(conn,stmt,rs); 177 } 178 } 179 180 /** 181 * @Method: clobReplace 182 * @Description:替換CLOB對象(將原CLOB對象清除,換成一個全新的CLOB對象) 183 * @Anthor:孤傲蒼狼 184 * 185 * @throws Exception 186 */ 187 @Test 188 public void clobReplace() throws Exception { 189 Connection conn = null; 190 PreparedStatement stmt = null; 191 ResultSet rs = null; 192 conn = JdbcUtils.getOracleConnection(); 193 boolean defaultCommit = conn.getAutoCommit(); 194 // 開啓事務 195 conn.setAutoCommit(false); 196 try { 197 /* 清空原CLOB對象 */ 198 String sql = "UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID=?"; 199 stmt = conn.prepareStatement(sql); 200 stmt.setInt(1, 1); 201 stmt.executeUpdate(); 202 203 /* 查詢CLOB對象並鎖定 */ 204 sql = "SELECT CLOBCOL FROM TEST_CLOB WHERE ID=? FOR UPDATE"; 205 stmt = conn.prepareStatement(sql); 206 stmt.setInt(1, 1); 207 rs = stmt.executeQuery(); 208 if (rs.next()) { 209 /* 獲取此CLOB對象 */ 210 oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL"); 211 /* 更新數據 */ 212 BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream()); 213 // 這種方式獲取的路徑,其中的空格會被使用「%20」代替 214 String path = JdbcOperaClob.class.getClassLoader().getResource("db.properties").getPath(); 215 // 將「%20」替換回空格 216 path = path.replaceAll("%20", " "); 217 BufferedReader in = new BufferedReader(new FileReader(path)); 218 int c; 219 while ((c = in.read()) != -1) { 220 out.write(c); 221 } 222 in.close(); 223 out.close(); 224 } 225 /* 正式提交 */ 226 conn.commit(); 227 } catch (Exception ex) { 228 /* 出錯回滾 */ 229 conn.rollback(); 230 throw ex; 231 } finally { 232 /* 恢復原提交狀態 */ 233 conn.setAutoCommit(defaultCommit); 234 JdbcUtils.release(conn, stmt, rs); 235 } 236 } 237 }
Oracle定義了一個BLOB字段用於保存二進制數據,但這個字段並不能存放真正的二進制數據,只能向這個字段存一個指針,而後把數據放到指針所指向的Oracle的LOB段中, LOB段是在數據庫內部表的一部分。於是在操做Oracle的Blob以前,必須得到指針(定位器)才能進行Blob數據的讀取和寫入。
如何得到表中的Blob指針呢? 能夠先使用insert語句向表中插入一個空的blob(調用oracle的函數empty_blob()),這將建立一個blob的指針,而後再把這個empty的blob的指針查詢出來,這樣就可獲得BLOB對象,從而讀寫blob數據了。架構
一、插入空blob:insert into testblob(id,image) values(?,empty_blob())
二、得到blob的cursor:併發
select image from testblob where id=? for update 注意: 必 須加for update鎖定該行,直至該行被修改完畢,保證不產生併發衝突。oracle
Blob b = rs.getBlob("image");
三、利用 io和獲取到的cursor往數據庫讀寫數據
注意:以上操做需開啓事務。函數
BLOB對象的存取範例工具
1 package me.gacl.demo; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.FileOutputStream; 6 import java.sql.Connection; 7 import java.sql.PreparedStatement; 8 import java.sql.ResultSet; 9 import org.junit.Test; 10 import me.gacl.utils.JdbcUtils; 11 12 /** 13 * @ClassName: JdbcOperaOracleBlob 14 * @Description:Oracle中大數據處理 15 * @author: 孤傲蒼狼 16 * @date: 2014-10-7 下午3:53:19 17 * 18 */ 19 public class JdbcOperaOracleBlob { 20 21 /** 22 * @Method: blobInsert 23 * @Description: 向數據庫中插入一個新的BLOB對象 24 * @Anthor:孤傲蒼狼 25 * 26 * @throws Exception 27 */ 28 @Test 29 public void blobInsert() throws Exception { 30 Connection conn = null; 31 PreparedStatement stmt = null; 32 ResultSet rs = null; 33 boolean defaultCommit = true; 34 try { 35 conn = JdbcUtils.getOracleConnection(); 36 //獲得數據庫事務處理的默認提交方式 37 defaultCommit = conn.getAutoCommit(); 38 //一、開啓事務 39 conn.setAutoCommit(false); 40 //二、插入一個空的BLOB對象 41 String sql = "INSERT INTO TEST_BLOB VALUES (?, EMPTY_BLOB())"; 42 stmt = conn.prepareStatement(sql); 43 stmt.setInt(1, 1); 44 stmt.executeUpdate(); 45 //三、查詢此BLOB對象並鎖定。注意: 必 須加for update鎖定該行,直至該行被修改完畢,保證不產生併發衝突 46 sql = "SELECT BLOBCOL FROM TEST_BLOB WHERE ID=? FOR UPDATE"; 47 stmt = conn.prepareStatement(sql); 48 stmt.setInt(1, 1); 49 rs = stmt.executeQuery(); 50 if (rs.next()) { 51 //四、取出此BLOB對象 ,並強制轉換成Oracle的BLOB對象 52 oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBCOL"); 53 //五、使用IO向BLOB對象中寫入數據 54 BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream()); 55 BufferedInputStream in = new BufferedInputStream(JdbcOperaOracleBlob.class.getClassLoader().getResourceAsStream("01.jpg")); 56 int c; 57 while ((c = in.read()) != -1) { 58 out.write(c); 59 } 60 in.close(); 61 out.close(); 62 } 63 //六、提交事務 64 conn.commit(); 65 } catch (Exception ex) { 66 //七、出錯回滾事務 67 conn.rollback(); 68 throw ex; 69 } finally { 70 //八、恢復數據庫事務處理的默認提交方式 71 conn.setAutoCommit(defaultCommit); 72 //釋放資源 73 JdbcUtils.release(conn, stmt, rs); 74 } 75 76 } 77 78 /** 79 * @Method: blobModify 80 * @Description:修改BLOB對象(是在原BLOB對象基礎上進行覆蓋式的修改) 81 * @Anthor:孤傲蒼狼 82 * 83 * @throws Exception 84 */ 85 @Test 86 public void blobModify() throws Exception { 87 Connection conn = null; 88 PreparedStatement stmt = null; 89 ResultSet rs = null; 90 boolean defaultCommit = true; 91 try { 92 conn = JdbcUtils.getOracleConnection(); 93 //獲得數據庫事務處理的默認提交方式 94 defaultCommit = conn.getAutoCommit(); 95 //一、開啓事務 96 conn.setAutoCommit(false); 97 //二、查詢此BLOB對象並鎖定。注意: 必 須加for update鎖定該行,直至該行被修改完畢,保證不產生併發衝突 98 String sql = "SELECT BLOBCOL FROM TEST_BLOB WHERE ID=? FOR UPDATE"; 99 stmt = conn.prepareStatement(sql); 100 stmt.setInt(1, 1); 101 rs = stmt.executeQuery(); 102 if (rs.next()) { 103 //三、取出此BLOB對象 ,並強制轉換成Oracle的BLOB對象 104 oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBCOL"); 105 //四、使用IO向BLOB對象中寫入數據 106 BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream()); 107 BufferedInputStream in = new BufferedInputStream(JdbcOperaOracleBlob.class.getClassLoader().getResourceAsStream("02.jpg")); 108 int c; 109 while ((c = in.read()) != -1) { 110 out.write(c); 111 } 112 in.close(); 113 out.close(); 114 } 115 //五、提交事務 116 conn.commit(); 117 } catch (Exception ex) { 118 //六、出錯回滾事務 119 conn.rollback(); 120 throw ex; 121 } finally { 122 //八、恢復數據庫事務處理的默認提交方式 123 conn.setAutoCommit(defaultCommit); 124 //釋放資源 125 JdbcUtils.release(conn, stmt, rs); 126 } 127 } 128 129 /** 130 * @Method: blobReplace 131 * @Description:替換BLOB對象(將原BLOB對象清除,換成一個全新的BLOB對象) 132 * @Anthor:孤傲蒼狼 133 * 134 * @throws Exception 135 */ 136 @Test 137 public void blobReplace() throws Exception { 138 Connection conn = null; 139 PreparedStatement stmt = null; 140 ResultSet rs = null; 141 boolean defaultCommit = true; 142 try { 143 conn = JdbcUtils.getOracleConnection(); 144 //獲得數據庫事務處理的默認提交方式 145 defaultCommit = conn.getAutoCommit(); 146 //一、開啓事務 147 conn.setAutoCommit(false); 148 //二、清空原BLOB對象 149 String sql = "UPDATE TEST_BLOB SET BLOBCOL=EMPTY_BLOB() WHERE ID=?"; 150 stmt = conn.prepareStatement(sql); 151 stmt.setInt(1, 1); 152 stmt.executeUpdate(); 153 //三、查詢此BLOB對象並鎖定。注意: 必 須加for update鎖定該行,直至該行被修改完畢,保證不產生併發衝突 154 sql = "SELECT BLOBCOL FROM TEST_BLOB WHERE ID=? FOR UPDATE"; 155 stmt = conn.prepareStatement(sql); 156 stmt.setInt(1, 1); 157 rs = stmt.executeQuery(); 158 if (rs.next()) { 159 //四、取出此BLOB對象 ,並強制轉換成Oracle的BLOB對象 160 oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBCOL"); 161 //五、使用IO向BLOB對象中寫入數據 162 BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream()); 163 BufferedInputStream in = new BufferedInputStream(JdbcOperaOracleBlob.class.getClassLoader().getResourceAsStream("01.jpg")); 164 int c; 165 while ((c = in.read()) != -1) { 166 out.write(c); 167 } 168 in.close(); 169 out.close(); 170 } 171 //六、提交事務 172 conn.commit(); 173 } catch (Exception ex) { 174 //七、出錯回滾事務 175 conn.rollback(); 176 throw ex; 177 } finally { 178 //八、恢復數據庫事務處理的默認提交方式 179 conn.setAutoCommit(defaultCommit); 180 //釋放資源 181 JdbcUtils.release(conn, stmt, rs); 182 } 183 } 184 185 /** 186 * @Method: blobRead 187 * @Description:BLOB對象讀取 188 * @Anthor:孤傲蒼狼 189 * 190 * @throws Exception 191 */ 192 @Test 193 public void blobRead() throws Exception { 194 Connection conn = null; 195 PreparedStatement stmt = null; 196 ResultSet rs = null; 197 boolean defaultCommit = true; 198 try { 199 conn = JdbcUtils.getOracleConnection(); 200 //獲得數據庫事務處理的默認提交方式 201 defaultCommit = conn.getAutoCommit(); 202 //一、開啓事務 203 conn.setAutoCommit(false); 204 //二、查詢BLOB對象 205 String sql = "SELECT BLOBCOL FROM TEST_BLOB WHERE ID=?"; 206 stmt = conn.prepareStatement(sql); 207 stmt.setInt(1, 1); 208 rs = stmt.executeQuery(); 209 if (rs.next()) { 210 //三、取出此BLOB對象 ,並強制轉換成Oracle的BLOB對象 211 oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBCOL"); 212 //四、以二進制流的形式輸出 213 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:/1.jpg")); 214 BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream()); 215 int c; 216 while ((c = in.read()) != -1) { 217 out.write(c); 218 } 219 in.close(); 220 out.close(); 221 } 222 //五、提交事務 223 conn.commit(); 224 } catch (Exception ex) { 225 //六、出錯回滾事務 226 conn.rollback(); 227 throw ex; 228 } finally { 229 //八、恢復數據庫事務處理的默認提交方式 230 conn.setAutoCommit(defaultCommit); 231 //釋放資源 232 JdbcUtils.release(conn, stmt, rs); 233 } 234 235 } 236 }
經過JDBC操縱Oracle數據庫的LOB字段,不外乎插入、修改、替換、讀取四種方式,掌握起來並不難。觀察上述程序對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。 例程中所有使用了緩衝操做類。