HVE 用户自定义函数UDF实例
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; import org.apache.hadoop.hive.serde2.lazy.LazyString; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; import org.apache.hadoop.io.Text; /** * TODO(根据国家代码返回国家中文名) * <p>本函数需要一个字典表文件: * AD 安道尔共和国 Andorra * AE 阿拉伯联合酋长国 United Arab Emirates * AF 阿富汗 Afghanistan * AG 安提瓜和巴布达 Antigua and Barbuda * @author 忘尘 * @Date 2020年6月1日 */ public class GenericUDFgetNameByCode extends GenericUDF{ // 加载静态资源 private static Map<String, String> countryMap = new HashMap<String, String>(); static { // 加载字典表文件到内存 InputStream in = null; // 读取字符流数据 BufferedReader reader = null; try { in = GenericUDFgetNameByCode.class.getClassLoader().getResourceAsStream("country"); reader = new BufferedReader(new InputStreamReader(in,"UTF-8")); // 加载数据 String line = null; // 截取数据 String[] strs = null; while ((line = reader.readLine()) != null) { // 读取到数据 strs = line.split("\t"); if (null != strs && strs.length == 3) { countryMap.put(strs[0], strs[1]); } } } catch (Exception e) { e.printStackTrace(); }finally { try { if (null != reader) { reader.close(); } if (null != in) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } } // initialize 校验参数 & 设定返回值类型 @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { // 进行参数的校验 // 要求:参数必须是简单的类型(primitive),并且还是简单类型中的string // 判断函数只接收一个参数 if (null != arguments && arguments.length == 1) { // 正常情况 // 判断是不是简单类型 if (arguments[0].getCategory() != ObjectInspector.Category.PRIMITIVE) { throw new UDFArgumentException("该函数该函数只能接收接收简单类型的参数!"); } // 判断是不是string类型 if (!arguments[0].getTypeName().toUpperCase().equals(PrimitiveObjectInspector.PrimitiveCategory.STRING.name())) { throw new UDFArgumentException("该函数只能接收string类型的参数"); } } else { // 不正常情况 throw new UDFArgumentException("该函数需要接收参数!并且只能传递一个参数!"); } // 设定返回类型 string return PrimitiveObjectInspectorFactory.writableStringObjectInspector; } private Text outkey = new Text(); // UDF函数主要的业务逻辑 @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { // 获取参数 LazyString p1 = (LazyString)arguments[0].get(); // 转换 String countryCode = p1.toString(); // 获取这个国家名称 String countryName = countryMap.get(countryCode); // 判断 if (null == countryName) { countryName = "一个不知名的小国家"; } // hadoop中没有string 需要转为text outkey.set(countryName); return outkey; } // 调用错误的友情提示信息 @Override public String getDisplayString(String[] children) { return "该函数可以帮助你返回国家名称,每次传入一个国家代码"; } }