String操作的细节——你的单位统一了吗?

在数据入库的时候,我们经常需要判断入库的字符串是否超长。如果字符串长度超长,需要分割字符串再存入数据库中。

这本是很正常的逻辑,但是在使用Java写入字符串到Oracle中在一种坑:如果你的Oracle表中使用了varchar类型,且单位是byte。那么使用Java进行字符串长度判断 及 字符串分割时,也需要按照 字节 的方式来进行处理,而不是 字符 的方式。

举例如下:

  • 错误方式
 // 按照字符方式进行判断及分割
String remark = "人工处理成失败";
if (remark.length() > 8) {
    
    
    remark = remark.substring(0, 8);
}
System.out.println(remark);
  • 正确方式
// 按照字节方式进行判断及分割
String remark = "人工处理成失败";
byte[] bytes = remark.getBytes();
if (bytes.length > 8) {
    
    
    remark = new String(Arrays.copyOfRange(bytes, 0,8));
}
System.out.println(remark);

如果使用上述的错误方式进行操作的话,可能会超过Oracle表设置的字节长度大小的,从而导致业务异常。

究其原因,还是因为Oracle数据库字段的定义 与 代码实现的基准不一致导致的。如果Oracle中varchar用byte作为基准进行存储,我们的Java代码中也要按照字节来进行计算,这样才能符合我们的预期。

可以看到,Java中String的字符及字节长度是有区别的:

String remark = "人工处理成失败";
// 字符长度为7
System.out.println(remark.length());
// 字节长度为21
System.out.println(remark.getBytes().length);

当然,如果你运行上面正确方式的代码,会发现结果中包含了乱码。这是因为Java中以3个字节组成一个字符(UTF-8),所以如果你不想乱码的话,截取的时候,将分割的长度设置为3的倍数就行了。

猜你喜欢

转载自blog.csdn.net/somehow1002/article/details/109018368