背景
由于Java对于数据库返回的clob类型不能直接当做String类型处理,需经过转换才可以读取。之前的转换代码如下:1
2
3
4
5
6
7
8public void setIp_clob(oracle.sql.CLOB ip_clob){
this.ip_clob = ip_clob;
try {
ip = ip_clob.getSubString(1, (int)ip_clob.getLength());
} catch (SQLException e) {
e.printStackTrace();
}
}
但是发现处理完返回给前台展示的数据不全。
排查
考虑可能转换代码中截取长度这儿存在问题,oracle.sql.CLOB有两种获取长度的方式:Clob.getLenth()
Clob.length()
分别打印出来:1
2System.out.println(ip_clob.length());
System.out.println(ip_clob.getLength());
输出为:1
23653
106
果然是不一样的,length()会长一点。
于是修改代码:1
2
3
4
5
6
7
8public void setIp_clob(oracle.sql.CLOB ip_clob){
this.ip_clob = ip_clob;
try {
ip = ip_clob.getSubString(1, (int)ip_clob.length());
} catch (SQLException e) {
e.printStackTrace();
}
}
注:在实际中,两者并非都是length()获取的更长,但根据length()获取的值来截取不会存在数据不全的问题。
修改了长度获取方式之后,问题就解决了。但通过getSubString()的方式不是很好,而且使用使用oracle.sql.COLB会存在于oracle驱动的强绑定。
还建议按如下方式处理:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import java.sql.Clob;
import org.apache.commons.io.IOUtils;
public void setIp_clob(Clob ip_clob){
this.ip_clob = ip_clob;
try {
ip = IOUtils.toString(ip_clob.getCharacterStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
通过调用java.sql.Clob,避难对oracle驱动的依赖,然后利用IOUtis包来进行处理得到string类型的输出。
拓展
关于oracle.sql.CLOB中的长度获取:
length():Implements the Clob interface method. Returns the number of characters in the CLOB value designated by this Clob object. Return length of the CLOB in characters。
https://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#length()
getLength(): Retreive the length of a datum. Return the length of the datum in bytes.
https://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/Datum.html#getLength()
可见length()是返回字符数,而getLength()为返回bytes数。