`
qindongliang1922
  • 浏览: 2151634 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:116451
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:124703
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:58677
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:70491
社区版块
存档分类
最新评论

jdbc操作Blob和Clob字段与字符串的转换

阅读更多
Oracle的数据库里对于大字段存储,通常有3种类型,一种就是所谓的Blob类型,另一种就是Clob类型,第三种是NClob类型,关于这三者者的使用范围,应该说没有严格意义上的要求,但大部分场景下我用经常使用Blob存储二进制数据类型的东西,例如图片,单子流等,而使用Clob来存储大型文本数据,例如一篇文献,或一个xml等等,但是更好的情况下建议使用NClob来存储双字节的文本数据,三者的存储方式如下表格所示

BLOBbyte
CLOBchar
NCLOBdouble char

使用时候,需要注意,一般使用char类型,或者double char类型,不会出现乱码情况,而使用byte类型存储文本类型,非常容易出现乱码,这一点,笔者深有体会,也许你存文本进BLOB字段时你可能感觉没问题,但是在取出来转换时一些特殊符号,有时候就莫名其妙的乱码了。所以对于文本类型,建议还是使用CLOB,或者NCLOB存储,以避免一些乱码问题.


另外需要注意的是:
如果你的单数据量只有几千个字符,建议按照varchar/varchar2方式存储,这样提高访问速度。但是对于几万或者更多的字符量,建议按照lob(clob/nclob)方式。

以下有几点请注意:
(1)面对插入的情况,应该首先对插入的blob/clob所在字段,赋予一个empty_blob()或empty_clob。再以更新方式,流形式插入
(2)所有的blob/clob对象(jdbc基本标准)没有实现对象序列化,一般第三方(vender)类包可能会重新实现,比如weblogic的jDriver for oracle
(3)在从数据库获取clob/blob字段的时候,不一定就以blob/clob对象字节流获取(有可能就是以其它字节流方式获取)


下面给出blob与clob字段,在向数据库插入,以及读取时与字符串互相转换代码

(1) 插入BLOB字段类型
 File file = new File("E:\\测试图片\\dog.jpg");  
    int length = (int)file2.length();  
    InputStream f = new FileInputStream(file);  
    ps.setBinaryStream(1, f, length); 


(2) 数据库插入CLOB字段类型
 File file = new File("E:\\测试数据\\文献评估.txt");  
    int length = (int)file.length();  
    InputStream f = new FileInputStream(file);  
    ps.setAsciiStream(1, f, length);  

(3) BLOB字段转换成String字符串
 /**
	  * Blob字段的通用转换
	  * 注意可能出现乱码
	  * @return 转好的字符串,
	  * **/
	 public  String BlobToString(Blob blob){  
		   StringBuffer str=new StringBuffer();
		   //使用StringBuffer进行拼接
		   InputStream in=null;//输入字节流
		    try {  
		              in = blob.getBinaryStream();  
		            //一般接下来是把in的字节流写入一个文件中,但这里直接放进字符串  
		            byte[] buff=new byte[(int) blob.length()];  
		    //      byte[] buff=new byte[1024];  
		         //    byte[] b = new byte[blob.getBufferSize()];  
		        for(int i=0;(i=in.read(buff))>0;){  
		            str=str.append(new String(buff));  
		        }
		        return str.toString();
		       
		        
		        }catch (Exception e) {  
		        e.printStackTrace();  
		         } finally{
		        	 try{
		        	 in.close();
		        	 }catch(Exception e){
		        		 System.out.println("转换异常");
		        		 e.printStackTrace();
		        	 }
		         } 
		    return null;  
		}


(4) CLOB字段转换成String字符串
/**
	  * Clob字段的通用转换
	  * @return 转好的字符串,
	  * **/
	    public static String ClobToString(CLOB clob) throws SQLException, IOException {   
	        String reString = "";   //拼接变量
	        Reader is = clob.getCharacterStream();// 得到流   
	        BufferedReader br = new BufferedReader(is);   
	        String s = br.readLine();   
	        StringBuffer sb = new StringBuffer();   
	        while (s != null) {  
	        sb.append(s);   
	        s = br.readLine();   
	        }   
	    reString = sb.toString(); //转换成字符串,进行返回  
	    return reString;   
	    }   


(5) 将字符串转换成BLOB,或者CLOB字段类型
 /**注意笔者是 Oracle11g
	  * @param 需要转换的参数
	  * 字符串转换成BLOB,CLOB,以及BLOB,CLOB转换成字符串
	 * @throws Exception 
	  * 
	  * */
	 public void covert(String str) throws Exception{
	     
		  try {
			  Clob c = new SerialClob(str.toCharArray());//String 转 clob
			 	        Blob b = new SerialBlob(str.getBytes("GBK"));//String 转 blob
			  	//      也可以这样不传字符集名称,默认使用系统的
			  	//      Blob b = new SerialBlob(s1.getBytes());
			 	         
			  	        String clobString = c.getSubString(1, (int) c.length());//clob 转 String
			  	        String blobString = new String(b.getBytes(1, (int) b.length()),"GBK");//blob 转 String
			  	//      前面若没传入字符集名称,则这里也不需要传入,以免出错
			  	//      String blobString = new String(b.getBytes(1, (int) b.length()));
			  	         
			 	        System.out.println(clobString);
			 	        System.out.println(blobString);
			
		} catch (SerialException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	 }


至此,大字段的数据类型的转换,插入,都可以实现了,另外需要注意的是,笔者的测试是在JDK7的版本和Oracle 11g的数据库下测试的,一些低的版本的JDK有些API可能不一样。



分享到:
评论
1 楼 eshore_pal 2013-08-19  
楼主有没有遇到过这种情况:通过ps.setString(4, log.getOutputData());outputdata数据库字段类型是NCLOB,如果outputdata字段长度太长就会出现乱码的情况。测试过1900个字符不会有乱码,超过1900个字符就出现乱码了。

相关推荐

Global site tag (gtag.js) - Google Analytics