java之clob类型数据的处理

背景

由于Java对于数据库返回的clob类型不能直接当做String类型处理,需经过转换才可以读取。之前的转换代码如下:

1
2
3
4
5
6
7
8
public 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
2
System.out.println(ip_clob.length());
System.out.println(ip_clob.getLength());

输出为:

1
2
3653
106

果然是不一样的,length()会长一点。

于是修改代码:

1
2
3
4
5
6
7
8
public 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
15
import 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数。