網絡上不少關於JAVA對Oracle中BLOB、CLOB類型字段的操做說明,有的不夠全面,有的不夠準確,甚至有的簡直就是胡說八道。最近的項目正巧用到了這方面的知識,在這裏作個總結。
環境:
Database: Oracle 9i
App Server: BEA Weblogic 8.14
表結構:
CREATE TABLE TESTBLOB (ID Int, NAME Varchar2(20), BLOBATTR Blob)
CREATE TABLE TESTBLOB (ID Int, NAME Varchar2(20), CLOBATTR Clob)
JAVA能夠經過JDBC,也能夠經過JNDI訪問並操做數據庫,這兩種方式的具體操做存在着一些差別,因爲經過App Server的數據庫鏈接池JNDI得到的數據庫鏈接提供的java.sql.Blob和java.sql.Clob實現類與JDBC方式提供的不一樣,所以在入庫操做的時候須要分別對待;出庫操做沒有這種差別,所以不用單獨對待。
1、BLOB操做
一、入庫
(1)JDBC方式
//經過JDBC得到數據庫鏈接
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");
con.setAutoCommit(false);
Statement st = con.createStatement();
//插入一個空對象empty_blob()
st.executeUpdate("insert into TESTBLOB (ID, NAME, BLOBATTR) values (1, "thename", empty_blob())");
//鎖定數據行進行更新,注意「for update」語句
ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1 for update");
if (rs.next())
{
//獲得java.sql.Blob對象後強制轉換爲oracle.sql.BLOB
oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBATTR");
OutputStream outStream = blob.getBinaryOutputStream();
//data是傳入的byte數組,定義:byte[] data
outStream.write(data, 0, data.length);
}
outStream.flush();
outStream.close();
con.commit();
con.close();
(2)JNDI方式
//經過JNDI得到數據庫鏈接
Context context = new InitialContext();
ds = (DataSource) context.lookup("ORA_JNDI");
Connection con = ds.getConnection();
con.setAutoCommit(false);
Statement st = con.createStatement();
//插入一個空對象empty_blob()
st.executeUpdate("insert into TESTBLOB (ID, NAME, BLOBATTR) values (1, "thename", empty_blob())");
//鎖定數據行進行更新,注意「for update」語句
ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1 for update");
if (rs.next())
{
//獲得java.sql.Blob對象後強制轉換爲weblogic.jdbc.vendor.oracle.OracleThinBlob(不一樣的App Server對應的可能會不一樣)
weblogic.jdbc.vendor.oracle.OracleThinBlob blob = (weblogic.jdbc.vendor.oracle.OracleThinBlob) rs.getBlob("BLOBATTR");
OutputStream outStream = blob.getBinaryOutputStream();
//data是傳入的byte數組,定義:byte[] data
outStream.write(data, 0, data.length);
}
outStream.flush();
outStream.close();
con.commit();
con.close();
二、出庫
//得到數據庫鏈接
Connection con = ConnectionFactory.getConnection();
con.setAutoCommit(false);
Statement st = con.createStatement();
//不須要「for update」
ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1");
if (rs.next())
{
java.sql.Blob blob = rs.getBlob("BLOBATTR");
InputStream inStream = blob.getBinaryStream();
//data是讀出並須要返回的數據,類型是byte[]
data = new byte[input.available()];
inStream.read(data);
inStream.close();
}
inStream.close();
con.commit();
con.close();
2、CLOB操做
一、入庫
(1)JDBC方式
//經過JDBC得到數據庫鏈接
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");
con.setAutoCommit(false);
Statement st = con.createStatement();
//插入一個空對象empty_clob()
st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");
//鎖定數據行進行更新,注意「for update」語句
ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");
if (rs.next())
{
//獲得java.sql.Clob對象後強制轉換爲oracle.sql.CLOB
oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBATTR");
Writer outStream = clob.getCharacterOutputStream();
//data是傳入的字符串,定義:String data
char[] c = data.toCharArray();
outStream.write(c, 0, c.length);
}
outStream.flush();
outStream.close();
con.commit();
con.close();
(2)JNDI方式
//經過JNDI得到數據庫鏈接
Context context = new InitialContext();
ds = (DataSource) context.lookup("ORA_JNDI");
Connection con = ds.getConnection();
con.setAutoCommit(false);
Statement st = con.createStatement();
//插入一個空對象empty_clob()
st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");
//鎖定數據行進行更新,注意「for update」語句
ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");
if (rs.next())
{
//獲得java.sql.Clob對象後強制轉換爲weblogic.jdbc.vendor.oracle.OracleThinClob(不一樣的App Server對應的可能會不一樣)
weblogic.jdbc.vendor.oracle.OracleThinClob clob = (weblogic.jdbc.vendor.oracle.OracleThinClob) rs.getClob("CLOBATTR");
Writer outStream = clob.getCharacterOutputStream();
//data是傳入的字符串,定義:String data
char[] c = data.toCharArray();
outStream.write(c, 0, c.length);
}
outStream.flush();
outStream.close();
con.commit();
con.close();
二、出庫
//得到數據庫鏈接
Connection con = ConnectionFactory.getConnection();
con.setAutoCommit(false);
Statement st = con.createStatement();
//不須要「for update」
ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1");
if (rs.next())
{
java.sql.Clob clob = rs.getClob("CLOBATTR");
Reader inStream = clob.getCharacterStream();
char[] c = new char[(int) clob.length()];
inStream.read(c);
//data是讀出並須要返回的數據,類型是String
data = new String(c);
inStream.close();
}
inStream.close();
con.commit();
con.close();
須要注意的地方:
一、java.sql.Blob、oracle.sql.BLOB、weblogic.jdbc.vendor.oracle.OracleThinBlob幾種類型的區別
二、java.sql.Clob、oracle.sql.CLOB、weblogic.jdbc.vendor.oracle.OracleThinClob幾種類型的區別
公司項目中的用法(博客):
入庫:先插一個oracle.sql.CLOB.empty_lob()進去,而後
String updateBaseSourceSql = "select content from mb_baseSource where id = ? for update";
conn.setAutoCommit(false);
ps = conn.prepareStatement(updateBaseSourceSql);
ps.setLong(1, result);
ResultSet rs = ps.executeQuery();
oracle.sql.CLOB clob = null;
if (rs.next()) {
clob = (oracle.sql.CLOB) rs.getClob(1);
}
Writer wr = clob.getCharacterOutputStream();
wr.write(baseSource[4]);
wr.flush();
wr.close();
rs.close();
ps.close();
conn.commit();
出庫:
findBaseSourceSql = "select content from mb_baseSource where id = ?"; ps = conn.prepareStatement(findBaseSourceSql); ps.setLong(1, sourceID); rs = ps.executeQuery(); if (rs.next()) { CLOB clob = (oracle.sql.CLOB) rs.getClob(1); if (clob != null) { Reader is = clob.getCharacterStream(); BufferedReader br = new BufferedReader(is); String s = br.readLine(); while (s != null) { result[6] += s; s = br.readLine(); } } } rs.close(); ps.close(); conn.close();