Oracle的数据库里对于大字段存储,通常有3种类型,一种就是所谓的Blob类型,另一种就是Clob类型,第三种是NClob类型,关于这三者者的使用范围,应该说没有严格意义上的要求,但大部分场景下我用经常使用Blob存储二进制数据类型的东西,例如图片,单子流等,而使用Clob来存储大型文本数据,例如一篇文献,或一个xml等等,但是更好的情况下建议使用NClob来存储双字节的文本数据,三者的存储方式如下表格所示
使用时候,需要注意,一般使用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字段类型
(2) 数据库插入CLOB字段类型
(3) BLOB字段转换成String字符串
(4) CLOB字段转换成String字符串
(5) 将字符串转换成BLOB,或者CLOB字段类型
至此,大字段的数据类型的转换,插入,都可以实现了,另外需要注意的是,笔者的测试是在JDK7的版本和Oracle 11g的数据库下测试的,一些低的版本的JDK有些API可能不一样
BLOB | byte |
CLOB | char |
NCLOB | double 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可能不一样