一、问题背景
之前公司在使用datax时,需要从rds同步数据到hive,但是数据库中的主键id是uuid类型的字符串,使用datax默认的字符串分隔方式,其实会有很大的问题,所以官方也不推荐使用。
二. 分析源码
跟踪底层源码最终可以定位到这个RangeSplitUtil类上
public static String[] doAsciiStringSplit(String left, String right, int expectSliceNumber) {
int radix = 128;
BigInteger[] tempResult = doBigIntegerSplit(stringToBigInteger(left, radix),
stringToBigInteger(right, radix), expectSliceNumber);
String[] result = new String[tempResult.length];
//处理第一个字符串(因为:在转换为数字,再还原的时候,如果首字符刚好是 basic,则不知道应该添加多少个 basic)
result[0] = left;
result[tempResult.length - 1] = right;
for (int i = 1, len = tempResult.length - 1; i < len; i++) {
result[i] = bigIntegerToString(tempResult[i], radix);
}
return result;
}
/**
* 由于只支持 ascii 码对应字符,所以radix 范围为[1,128]
*/
public static BigInteger stringToBigInteger(String aString, int radix) {
if (null == aString) {
throw new IllegalArgumentException("参数 bigInteger 不能为空.");
}
checkIfBetweenRange(radix, 1, 128);
BigInteger result = BigInteger.ZERO;
BigInteger radixBigInteger = BigInteger.valueOf(radix);
int tempChar;
int k = 0;
for (int i = aString.length() - 1; i >= 0; i--) {
tempChar = aString.charAt(i);
if (tempChar >= 128) {
throw new IllegalArgumentException(String.format("根据字符串进行切分时仅支持 ASCII 字符串,而字符串:[%s]非 ASCII 字符串.", aString));
}
result = result.add(BigInteger.valueOf(tempChar).multiply(radixBigInteger.pow(k)));
k++;
}
return result;
}
/**
* 把BigInteger 转

最低0.47元/天 解锁文章
1万+





