Sqoop处理Clob与Blob字段

[Author]: kwu 

Sqoop处理Clob与Blob字段,在Oracle中Clob为大文本,Blob存储二进制文件。遇到这类字段导入hive或者hdfs需要特殊处理。

1、oracle中的测试表

[sql]  view plain copy
  1. CREATE TABLE  
  2.     T_LOB  
  3.     (  
  4.         A INTEGER,  
  5.         B CLOB,  
  6.         C BLOB  
  7.     )  

测试数据

[sql]  view plain copy
  1. insert into T_LOB (A, B, C) values (1, 'clob测试',to_blob('3456'));  


2、sqoop脚本

[plain]  view plain copy
  1. import  
  2. --append  
  3. --connect  
  4. jdbc:oracle:thin:@localhost:1521/orcl  
  5. --username  
  6. wuke  
  7. --password  
  8. Abcd1234  
  9. --table  
  10. BDC_TEST.T_LOB  
  11. --columns  
  12. "A,B,C"  
  13. --target-dir   
  14. /tmp/t_lob  
  15.   
  16. -m  
  17. 1  
执行脚本

[plain]  view plain copy
  1. sqoop --options-file ./importHdfs.opt  



3、查看生成的HDFS文件


可以看出,clob的字段是导入到hdfs上是正常显示文本,blob是二进制文件导出到hdfs上显示为16进制

16进制转换为string可采用如下方法,实际上通过移位操作来实现:

[java]  view plain copy
  1. package com.ganymede.test;  
  2.   
  3. /** 
  4.  * 十六进制的转换操作 
  5.  * @author Ganymede 
  6.  * 
  7.  */  
  8. public class Hex {  
  9.   
  10.     /** 
  11.      * 用于建立十六进制字符的输出的小写字符数组 
  12.      */  
  13.     private static final char[] DIGITS_LOWER = { '0''1''2''3''4''5',  
  14.             '6''7''8''9''a''b''c''d''e''f' };  
  15.   
  16.     /** 
  17.      * 用于建立十六进制字符的输出的大写字符数组 
  18.      */  
  19.     private static final char[] DIGITS_UPPER = { '0''1''2''3''4''5',  
  20.             '6''7''8''9''A''B''C''D''E''F' };  
  21.   
  22.     /** 
  23.      * 将字节数组转换为十六进制字符数组 
  24.      *  
  25.      * @param data 
  26.      *            byte[] 
  27.      * @return 十六进制char[] 
  28.      */  
  29.     public static char[] encodeHex(byte[] data) {  
  30.         return encodeHex(data, true);  
  31.     }  
  32.   
  33.     /** 
  34.      * 将字节数组转换为十六进制字符数组 
  35.      *  
  36.      * @param data 
  37.      *            byte[] 
  38.      * @param toLowerCase 
  39.      *            true 传换成小写格式 , false 传换成大写格式 
  40.      * @return 十六进制char[] 
  41.      */  
  42.     public static char[] encodeHex(byte[] data, boolean toLowerCase) {  
  43.         return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);  
  44.     }  
  45.   
  46.     /** 
  47.      * 将字节数组转换为十六进制字符数组 
  48.      *  
  49.      * @param data 
  50.      *            byte[] 
  51.      * @param toDigits 
  52.      *            用于控制输出的char[] 
  53.      * @return 十六进制char[] 
  54.      */  
  55.     protected static char[] encodeHex(byte[] data, char[] toDigits) {  
  56.         int l = data.length;  
  57.         char[] out = new char[l << 1];  
  58.         // two characters form the hex value.  
  59.         for (int i = 0, j = 0; i < l; i++) {  
  60.             out[j++] = toDigits[(0xF0 & data[i]) >>> 4];  
  61.             out[j++] = toDigits[0x0F & data[i]];  
  62.         }  
  63.         return out;  
  64.     }  
  65.   
  66.     /** 
  67.      * 将字节数组转换为十六进制字符串 
  68.      *  
  69.      * @param data 
  70.      *            byte[] 
  71.      * @return 十六进制String 
  72.      */  
  73.     public static String encodeHexStr(byte[] data) {  
  74.         return encodeHexStr(data, true);  
  75.     }  
  76.   
  77.     /** 
  78.      * 将字节数组转换为十六进制字符串 
  79.      *  
  80.      * @param data 
  81.      *            byte[] 
  82.      * @param toLowerCase 
  83.      *            true 传换成小写格式 , false 传换成大写格式 
  84.      * @return 十六进制String 
  85.      */  
  86.     public static String encodeHexStr(byte[] data, boolean toLowerCase) {  
  87.         return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);  
  88.     }  
  89.   
  90.     /** 
  91.      * 将字节数组转换为十六进制字符串 
  92.      *  
  93.      * @param data 
  94.      *            byte[] 
  95.      * @param toDigits 
  96.      *            用于控制输出的char[] 
  97.      * @return 十六进制String 
  98.      */  
  99.     protected static String encodeHexStr(byte[] data, char[] toDigits) {  
  100.         return new String(encodeHex(data, toDigits));  
  101.     }  
  102.   
  103.     /** 
  104.      * 将十六进制字符数组转换为字节数组 
  105.      *  
  106.      * @param data 
  107.      *            十六进制char[] 
  108.      * @return byte[] 
  109.      * @throws RuntimeException 
  110.      *             如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常 
  111.      */  
  112.     public static byte[] decodeHex(char[] data) {  
  113.   
  114.         int len = data.length;  
  115.   
  116.         if ((len & 0x01) != 0) {  
  117.             throw new RuntimeException("Odd number of characters.");  
  118.         }  
  119.   
  120.         byte[] out = new byte[len >> 1];  
  121.   
  122.         // two characters form the hex value.  
  123.         for (int i = 0, j = 0; j < len; i++) {  
  124.             int f = toDigit(data[j], j) << 4;  
  125.             j++;  
  126.             f = f | toDigit(data[j], j);  
  127.             j++;  
  128.             out[i] = (byte) (f & 0xFF);  
  129.         }  
  130.   
  131.         return out;  
  132.     }  
  133.   
  134.     /** 
  135.      * 将十六进制字符转换成一个整数 
  136.      *  
  137.      * @param ch 
  138.      *            十六进制char 
  139.      * @param index 
  140.      *            十六进制字符在字符数组中的位置 
  141.      * @return 一个整数 
  142.      * @throws RuntimeException 
  143.      *             当ch不是一个合法的十六进制字符时,抛出运行时异常 
  144.      */  
  145.     protected static int toDigit(char ch, int index) {  
  146.         int digit = Character.digit(ch, 16);  
  147.         if (digit == -1) {  
  148.             throw new RuntimeException("Illegal hexadecimal character " + ch  
  149.                     + " at index " + index);  
  150.         }  
  151.         return digit;  
  152.     }  
  153.   
  154.     public static void main(String[] args) {  
  155.         String srcStr = "待转换字符串";  
  156.         String encodeStr = encodeHexStr(srcStr.getBytes());  
  157.         String decodeStr = new String(decodeHex(encodeStr.toCharArray()));  
  158.         System.out.println("转换前:" + srcStr);  
  159.         System.out.println("转换后:" + encodeStr);  
  160.         System.out.println("还原后:" + decodeStr);  
  161.           
  162.           
  163.         System.out.println("---------------------------------------");  
  164.         decodeStr = new String(decodeHex("3435363738390d0a626c6f62".toCharArray()));  
  165.         System.out.println("还原后:" + decodeStr);  
  166.     }  
  167.   
  168. }  

对于hive可以在入库前转换成string,或者直接入库后使用udf来转换

你可能感兴趣的:(Sqoop)