java實現往hive 的map類型字段寫數據
往hive 的map類型字段寫數據
該表的該字段類型是map<string,string>
對應類的該屬性的類型需要定義成String,不可定義成Map<String,String> !!
方法1:
建表語句定義map的分隔符:
row format delimited fields terminated by '|' collection items terminated by ',' map keys terminated by ':' NULL DEFINED AS ''
然後在java中封裝好map後,不可直接把map.toString()的字符串寫入字段(會有“=”,不能正確組成JSON格式的內容),也不可序列化為JSON格式的字符串後寫入字段(會加很多“\”)!需要自己定義toString的方法:
public static String insertToMap(Map<String, String> map) { StringBuilder sb = new StringBuilder(); Set<String> set = map.keySet(); for (String s : set) { sb.append(s).append(":").append(StringUtils.isBlank(map.get(s)) ? "NULL" : map.get(s)).append(","); } String str = sb.toString(); return str.substring(0, str.length() - 1); }
字符串是不帶雙引號和兩端花括號的字符串,這樣插入到字段時,hive會自動為key和value都添加雙引號,也會在兩端添加花括號!(為啥為空時需要把value設置成NULL?如果為空不寫時,怕hive處理時出錯,可能會處理成帶四個雙引號的NULL,所以手動指定空為”NULL”字符串)
方法2:
建表語句不用定義map的分隔符:
然後在java中封裝好map後,不可直接把map.toString()的字符串寫入字段,也不可序列化為JSON格式的字符串後寫入字段!需要自己定義toString的方法:
public static String insertToMap(Map<String, String> map) { StringBuilder sb = new StringBuilder(); Set<String> set = map.keySet(); for (String s : set) { sb.append(s).append("\003").append(StringUtils.isBlank(map.get(s)) ? "NULL" : map.get(s)).append("\002"); } String str = sb.toString(); return str.substring(0, str.length() - 1); }
得到的則是正確的字段內容!
hive中默認是用“\003”分隔key與value,用“\002”分隔兩個鍵值對!
以上是今天嘗試好幾種方法整理後的結論!
hive-map類型字段的定義與插入
map類型定義瞭一種kv結構,在hive中經常使用。
如何定義map類型呢?
create table employee(id string, perf map<string, int>) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ',' MAP KEYS TERMINATED BY ':';
其中fields是字段分隔符,collection是每個kv對的分隔符,map keys是k與v的分隔符。
導入數據時,隻需要按對應分隔符處理好數據即可。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java實用工具之StringJoiner詳解
- 關於StringUtils.isBlank()的使用及說明
- hive從mysql導入數據量變多的解決方案
- java基礎之 Arrays.toString()方法詳解
- Java那點兒事之Map集合不為人知的秘密有哪些