在OracleQueryBean類中增加一個(gè)函數(shù),來(lái)進(jìn)行讀取,具體代碼如下:
成都創(chuàng)新互聯(lián)公司擁有十載成都網(wǎng)站建設(shè)工作經(jīng)驗(yàn),為各大企業(yè)提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)服務(wù),對(duì)于網(wǎng)頁(yè)設(shè)計(jì)、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、app開發(fā)定制、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、程序開發(fā)、網(wǎng)站優(yōu)化(SEO優(yōu)化)、微網(wǎng)站、申請(qǐng)域名等,憑借多年來(lái)在互聯(lián)網(wǎng)的打拼,我們?cè)诨ヂ?lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了很多網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷經(jīng)驗(yàn),集策劃、開發(fā)、設(shè)計(jì)、營(yíng)銷、管理等網(wǎng)站化運(yùn)作于一體,具備承接各種規(guī)模類型的網(wǎng)站建設(shè)項(xiàng)目的能力。
/**
* 根據(jù)圖片在數(shù)據(jù)庫(kù)中的ID進(jìn)行讀取
* @param strID 圖片字段ID
* @param w 需要縮到的寬度
* @param h 需要縮到高度
* @return
*/
public byte[] GetImgByteById(String strID, int w, int h){
//System.out.println("Get img data which id is " + nID);
if(myConnection == null)
this.getConnection();
byte[] data = null;
try {
Statement stmt = myConnection.createStatement();
ResultSet myResultSet = stmt.executeQuery("select " + this.strIDName + " from " + this.strTabName + " where " + this.strIDName + "=" + strID);
StringBuffer myStringBuffer = new StringBuffer();
if (myResultSet.next()) {
Blob...好像不是常用類型,是自定義的吧。
好吧,最簡(jiǎn)單的方法。
假設(shè)已知File類型的file1。
List
testList=new
ArrayList();
testList.add(file1);
Blob
blob=(Blob)testList.get(0);
如果可以強(qiáng)轉(zhuǎn)的話,以上代碼均有效。換句話說(shuō)只要Blob是File類型的子類以上代碼就有效,否則報(bào)錯(cuò),無(wú)法強(qiáng)轉(zhuǎn)。
1.使用jdk中的方法進(jìn)行傳輸。在ResultSet 中有g(shù)etBlob()方法,在PreparedStatement中有setBlob()方法,所以大多數(shù)人都會(huì)嘗試setBlob
(),getBlob() 進(jìn)行讀寫,或者兩個(gè)數(shù)據(jù)庫(kù)之間BLOB的傳輸。這種方法實(shí)際上是行不通的,據(jù)網(wǎng)上的一些資料介紹,說(shuō)sun官方的文檔有些方法
都是錯(cuò)誤的。
2.使用ResultSet.getBinaryStream 和PreparedStatement.setBinaryStream對(duì)BLOB進(jìn)行讀寫或兩個(gè)數(shù)據(jù)庫(kù)間的傳輸。這種方法我自己嘗試過(guò),
發(fā)現(xiàn),如果BLOB中存儲(chǔ)的是文本文件的話,就沒(méi)問(wèn)題,如果是二進(jìn)制文件,傳輸就會(huì)有問(wèn)題。
根據(jù)自己的經(jīng)驗(yàn),以及查閱了Oracle的官方文檔,都是使用如下處理方法:
1.新建記錄,插入BLOB數(shù)據(jù)
1.1首先新建記錄的時(shí)候,使用oracle的函數(shù)插入一個(gè)空的BLOB,假設(shè)字段A是BLOB類型的:
insert xxxtable(A,B,C) values(empty_blob(),'xxx','yyyy')
1.2后面再查詢剛才插入的記錄,然后更新BLOB,在查詢前,注意設(shè)置Connection的一個(gè)屬性:
conn.setAutoCommit(false);如果缺少這一步,可能導(dǎo)致fetch out of sequence等異常.
1.3 查詢剛才插入的記錄,后面要加“ for update ”,如下:
select A from xxxtable where xxx=999 for update ,如果缺少for update,可能出現(xiàn)row containing the LOB value is not locked
的異常
1.4 從查詢到的 BLOB字段中,獲取blob并進(jìn)行更新,代碼如下:
BLOB blob = (BLOB) rs.getBlob("A");
OutputStream os = blob.getBinaryOutputStream();
BufferedOutputStream output = new BufferedOutputStream(os);
后面再使用output.write方法將需要寫入的內(nèi)容寫到output中就可以了。例如我們將一個(gè)文件寫入這個(gè)字段中:
BufferedInputStream input = new BufferedInputStream(new File("c://hpWave.log").toURL().openStream());
byte[] buff = new byte[2048];? //用做文件寫入的緩沖
int bytesRead;
while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
output.write(buff, 0, bytesRead);
System.out.println(bytesRead);
}
上面的代碼就是從input里2k地讀取,然后寫入到output中。
1.5上面執(zhí)行完畢后,記得關(guān)閉output,input,以及關(guān)閉查詢到的ResultSet
1.6最后執(zhí)行conn.commit();將更新的內(nèi)容提交,以及執(zhí)行conn.setAutoCommit(true); 改回Connction的屬性
2.修改記錄,方法與上面的方法類似,
2.1首先更新BLOB以外的其他字段
2.2 使用1.3中類似的方法獲取記錄
2.3 修改的過(guò)程中,注意以下:a 需要更新的記錄中,BLOB有可能為NULL,這樣在執(zhí)行blob.getBinaryOutputStream()獲取的值可能為
null,那么就關(guān)閉剛才select的記錄,再執(zhí)行一次update xxxtable set A = empty_blob() where xxx, 這樣就先寫入了一個(gè)空的BLOB(不是null),然后再
使用1.3,1.4中的方法執(zhí)行更新記錄.b 注意別忘了先執(zhí)行setAutoCommit(false),以及"for update",以及后面的conn.commit();等。
3.讀取BLOB字段中的數(shù)據(jù).
3.1 讀取記錄不需要setAutoCommit(),以及 select ....for update.
3.2 使用普通的select 方法查詢出記錄
3.3 從ResultSet中獲取BLOB并讀取,如下:
BLOB b_to = (BLOB) rs.getBlob("A");
InputStream is = b_from.getBinaryStream();
BufferedInputStream input = new BufferedInputStream(is);
byte[] buff = new byte[2048];
while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
//在這里執(zhí)行寫入,如寫入到文件的BufferedOutputStream里
System.out.println(bytesRead);
}
通過(guò)循環(huán)取出blob中的數(shù)據(jù),寫到buff里,再將buff的內(nèi)容寫入到需要的地方
4.兩個(gè)數(shù)據(jù)庫(kù)間blob字段的傳輸
類似上面1和3的方法,一邊獲取BufferedOutputStream,另外一邊獲取BufferedInputStream,然后讀出寫入,需要注意的是寫入所用的
Connection要執(zhí)行conn.setAutoCommit(false);以及獲取記錄時(shí)添加“ for update ”以及最后的commit();
總結(jié)以上方法,其根本就是先創(chuàng)建空的BLOB,再獲取其BufferedOutputStream進(jìn)行寫入,或獲取BufferedInputStream進(jìn)行讀取
(1)對(duì)數(shù)據(jù)庫(kù)clob型執(zhí)行插入操作?
*************************************************?
java.sql.PreparedStatement?pstmt?=?null;?
ResultSet?rs?=?null;?
String?query?=?"";?
conn.setAutoCommit(false);?
query?=?"insert?into?clobtest_table(id,picstr)?values(?,empty_clob())";?
java.sql.PreparedStatement?pstmt?=?conn.prepareStatement(query);?
pstmt.setString(1,"001");?
pstmt.executeUpdate();?
pstmt?=?null?
query?=?"select?picstr?from?clobtest_table?where?id?=?'001'?for?update";?
pstmt?=?con.prepareStatement(query)?
rs=?pstmt.executeQuery();?
oracle.sql.CLOB?clobtt?=?null;?
if(rs.next()){?
clobtt?=?(oracle.sql.CLOB)rs.getClob(1);?
}?
Writer?wr?=?clobtt.getCharacterOutputStream();?
wr.write(strtmp);?
wr.flush();?
wr.close();?
rs.close();?
con.commit();?
(2)通過(guò)sql/plus查詢是否已經(jīng)成功插入數(shù)據(jù)庫(kù)?
*************************************************?
PL/SQL的包DBMS_LOB來(lái)處理LOB數(shù)據(jù)。察看剛才的插入是否成功。使用DBMS_LOB包的getlength這個(gè)procedure來(lái)檢測(cè)是否已經(jīng)將str存入到picstr字段中了。如:?
SQL?select?dbms_lob.getlength(picstr)?from?clobtest_table;?
(3)對(duì)數(shù)據(jù)庫(kù)clob型執(zhí)行讀取操作?
*************************************************?
讀取相對(duì)插入就很簡(jiǎn)單了?;静襟E和一半的取數(shù)據(jù)庫(kù)數(shù)據(jù)沒(méi)有太大的差別。?
String?description?=?""?
query?=?"select?picstr?from?clobtest_table?where?id?=?'001'";?
pstmt?=?con.prepareStatement(query);?
ResultSet?result?=?pstmt.executeQuery();?
if(result.next()){?
oracle.jdbc.driver.OracleResultSet?ors?=?
(oracle.jdbc.driver.OracleResultSet)result;?
oracle.sql.CLOB?clobtmp?=?(oracle.sql.CLOB)?ors.getClob(1);?
if(clobtmp==null?||?clobtmp.length()==0){?
System.out.println("======CLOB對(duì)象為空?");?
description?=?"";?
}else{?
description=clobtmp.getSubString((long)1,(int)clobtmp.length());?
System.out.println("======字符串形式?"+description);?
}?
}