最近項目用到了對oracle大字段的讀寫,小白在這裡記錄下,方便自己以後用到,也希望對其他朋友有一點幫助。
由於項目的原因,這裡的blob只是對xml報文的讀寫,並沒有涉及到保存圖片等,因此下面涉及的方法可能不全面,如有需要請自行查看其它大神博客。
一、讀blob
這裡對blob的讀是直接在數據庫建了一個函數Blob_To_Varchar ,這樣方便項目裡面其它地方用到查詢blob:
CREATE OR REPLACE Function Blob_To_Varchar (Blob_In In Blob) Return Varchar2
Is
V_Varchar Varchar2(4000);
V_Start Pls_Integer := 1;
V_Buffer Pls_Integer := 4000;
Begin
If Dbms_Lob.Getlength(Blob_In) Is Null Then
Return '';
End If;
For I In 1..Ceil(Dbms_Lob.Getlength(Blob_In) / V_Buffer) Loop
--當轉換出來的字符串亂碼時,可嘗試用注釋掉的函數
--V_Varchar := Utl_Raw.Cast_To_Varchar2(Utl_Raw.Convert(Dbms_Lob.Substr(Blob_In, V_Buffer, V_Start),'SIMPLIFIED CHINESE_CHINA.ZHS16GBK', 'AMERICAN_THE NETHERLANDS.UTF8'));
V_Varchar := Utl_Raw.Cast_To_Varchar2(Dbms_Lob.Substr(Blob_In, V_Buffer, V_Start));
V_Start := V_Start + V_Buffer;
End Loop;
Return V_Varchar;
End Blob_To_Varchar;
直接在sql裡面用創建的Blob_To_Varchar函數。
SELECT Blob_To_Varchar(req_tpl) as req_tpl FROM inf_xml;
二、寫blob
oracle存大數據的時候,要先插入一個empty_blob()占位符,占到blob字段,其次在查詢出來這個大字段用流的方式寫入。
首先是插入一個empty_blob()占位符
//插入數據
int insertLogInf = this.logControllerDao.insertLogInfo(params); if(insertLogInf > 0){
//插入大字段數據 for(int i=0;i<2;i++){ if(i == 0){ insertBlob(i,log_id,Const.getStrValue(params, "req_xml")); }else{ insertBlob(i,log_id,rsp_xml); } } }
insertBlob方法(由於要插入2個blob,又不能同時寫進去,所以用比較笨的方法循環下)
public void insertBlob(int i , String log_id ,String insertXml)throws Exception{
BLOB blobXML = null;
//查詢數據
LogInterfaceXML retLogInf = this.logControllerDao.queryBlobLogInfByLogid(log_id);
if(i == 0){
blobXML = (BLOB) retLogInf.getReq_xml();
}else{
blobXML = (BLOB) retLogInf.getRsp_xml();
}
OutputStream ops = null;
try {
byte[] data = null;
ops = blobXML.setBinaryStream(0);
data = insertXml.getBytes();
ops.write(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(ops!=null){
ops.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
這裡的req_xml rsp_xml 要用 Object
@Alias("logInterfaceXML")
public class LogInterfaceXML {
private String log_id;
private String op_code ;
private String req_time ;
private String rsp_time ;
private String ep_address ;
private String result_desc ;
private Object req_xml ;
private Object rsp_xml ;
public String getOp_code() {
return op_code;
}
public void setOp_code(String op_code) {
this.op_code = op_code;
}
public String getReq_time() {
return req_time;
}
public void setReq_time(String req_time) {
this.req_time = req_time;
}
public String getRsp_time() {
return rsp_time;
}
public void setRsp_time(String rsp_time) {
this.rsp_time = rsp_time;
}
public String getEp_address() {
return ep_address;
}
public void setEp_address(String ep_address) {
this.ep_address = ep_address;
}
public String getResult_desc() {
return result_desc;
}
public void setResult_desc(String result_desc) {
this.result_desc = result_desc;
}
public Object getReq_xml() {
return req_xml;
}
public void setReq_xml(Object req_xml) {
this.req_xml = req_xml;
}
public Object getRsp_xml() {
return rsp_xml;
}
public void setRsp_xml(Object rsp_xml) {
this.rsp_xml = rsp_xml;
}
public String getLog_id() {
return log_id;
}
public void setLog_id(String log_id) {
this.log_id = log_id;
}
}
對數據庫的操作用的是mybatis
<resultMap id="logInterfaceResultMap" type="logInterfaceXML">
<result property="log_id" column="id"/>
<result property="op_code" column="op_code"/>
<result property="req_time" column="req_time" />
<result property="rsp_time" column="rsp_time" />
<result property="ep_address" column="ep_address" />
<result property="req_xml" column="req_xml" jdbcType="BLOB" />
<result property="rsp_xml" column="rsp_xml" jdbcType="BLOB" />
<result property="result_desc" column="result_desc" />
</resultMap>
<select id="queryBlobLogInfByLogid" resultType="logInterfaceXML" parameterType="string" databaseId="oracle">
select * from inf_xml c where c.log_id = #{log_id} for update
</select>
<insert id="insertLogInfo" parameterType="map" databaseId="oracle">
insert into inf_xml (log_id,op_code,req_time,rsp_time,ep_address,req_xml,rsp_xml,state,result_desc)
values (#{log_id},#{op_code},to_date(#{req_time},'YYYY-MM-DD HH24:MI:SS'),to_date(#{rsp_time},'YYYY-MM-DD HH24:MI:SS'),#{ep_address},empty_blob(),empty_blob(),'1',#{result_desc})
</insert>
可能是由於網路問題,這裡寫入blob的xml數據,時不時的會出現延時問題。
如果馬上查詢數據的話,可能不一定有數據,要等會才有數據。
具體是什麼原因導致的,還在研究中,有哪位大神要是知道,可以告訴小弟一聲,謝謝了。