最近项目用到了对oracle大字段的读写,小白在这里记录下,方便本身之后用到,也但愿对其余朋友有一点帮助。sql
因为项目的缘由,这里的blob只是对xml报文的读写,并无涉及到保存图片等,所以下面涉及的方法可能不全面,若有须要请自行查看其它大神博客。数据库
1、读blobmybatis
这里对blob的读是直接在数据库建了一个函数Blob_To_Varchar ,这样方便项目里面其它地方用到查询blob:oracle
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;
2、写bloboop
(1)经过代码去实现blob的写入,比较麻烦。大数据
oracle存大数据的时候,要先插入一个empty_blob()占位符,占到blob字段,其次在查询出来这个大字段用流的方式写入。this
首先是插入一个empty_blob()占位符spa
//插入数据
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 要用 Objectcode
@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数据,时不时的会出现延时问题。
若是立刻查询数据的话,可能不必定有数据,要等会才有数据。
(2)在数据库建了一个函数VARCHAR_TO_BLOB进行blob的插入
CREATE OR REPLACE FUNCTION VARCHAR_TO_BLOB (b IN CLOB default empty_clob()) RETURN BLOB IS res BLOB; b_len number := dbms_lob.getlength(b) ; dest_offset1 NUMBER := 1; src_offset1 NUMBER := 1; amount_c INTEGER := DBMS_LOB.lobmaxsize; blob_csid NUMBER := DBMS_LOB.default_csid; lang_ctx INTEGER := DBMS_LOB.default_lang_ctx; warning INTEGER; BEGIN if b_len > 0 then DBMS_LOB.createtemporary (res, TRUE); DBMS_LOB.OPEN (res, DBMS_LOB.lob_readwrite); DBMS_LOB.convertToBlob (res, b, amount_c, dest_offset1, src_offset1, blob_csid, lang_ctx, warning ); else select empty_blob() into res from dual ; end if ; RETURN res; END VARCHAR_TO_BLOB;
直接在sql里面用建立的VARCHAR_TO_BLOB函数:
insert into test_detail(id,content) values(${id},VARCHAR_TO_BLOB(#{content}))