目 录
1、背景描述
2、环境信息
3、新建java项目
4、编写java类
5、导出jar包
6、注册jar包
7、使用自定义函数
8、删除自定义函数
Apache Hive用户自定义函数(UDF)有两个不同的接口:
org.apache.hadoop.hive.ql.exec.UDF org.apache.hadoop.hive.ql.udf.generic.GenericUDF
前者简单,用于函数读取和返回都是基础数据类型,后者复杂,用于操作嵌套数据结构,比如Map,List,Set等。下面将用简单API介绍一个自定义函数从java开发到部署到集群中使用的流程。
2、环境信息
本文在编写时,hive采用的是华为大数据平台FusionInsight HD 6.5(现在已经改名为MRS),不同大数据平台涉及到的差异主要是用户认证,权限和一些bug的修复,其他大体一致。
UDF开发语言采用java,jdk1.8。
3、新建java项目
创建一个名字随便取,符合规范的Project。

添加以下两个jar包,可以在下载的客户端中找到:FusionInsight_Services_ClientConfig\FusionInsight_Services_ClientConfig\Hive\jdbc
hive-exec-1.3.0.java
hadoop-common-2.7.2.jar
配置build path

4、编写java类
package com.xxx.xxx;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import org.apache.hadoop.hive.ql.exec.UDF;/**** @author 作 者:chenyunliang* @note 实现功能:* @note 此类实现检查身份证和转换身份证功能*/public class ValidateIDCardUDF extends UDF {// 中国公民身份证号码最小长度public static final int CHINA_ID_MIN_LENGTH = 15;// 中国公民身份证号码最大长度public static final int CHINA_ID_MAX_LENGTH = 18;// 中国公民身份证号码最大长度public static final int CHINA_ID_TWHKMK_LENGTH = 10;// 每位加权因子public static final int power[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };/**** @author 作 者:chenyunliang* @note 实现功能:* @note 此方法实现测试功能*/public static void main(String[] args) {ValidateIDCardUDF validateIDCardUDF = new ValidateIDCardUDF();System.out.println(validateIDCardUDF.evaluate("43061119850113118X"));// 370725881105149, 37072519881105149x}/**** @author 作 者:chenyunliang* @note 实现功能:* @note 此方法实现将15位身份证号码转换为18位功能*/public String evaluate(String cardID) {String cardID_18 = "";// 检查输入参数,必须是15位if (cardID.trim().length() == CHINA_ID_MAX_LENGTH) {return cardID.trim();} else if (cardID.trim().length() != CHINA_ID_MIN_LENGTH || !isNum(cardID)) {return null;}// 获取出生年月日String birthDayString = cardID.substring(6, 12);Date birthDate = null;try {birthDate = (Date) new SimpleDateFormat("yyMMdd").parse(birthDayString);} catch (Exception e) {e.printStackTrace();}// 通过日历来获取年份等Calendar calendar = Calendar.getInstance();if (null != birthDate) {calendar.setTime(birthDate);}String yearString = String.valueOf(calendar.get(Calendar.YEAR));cardID_18 = cardID.substring(0, 6) + yearString + cardID.substring(8);// 转换字符数组char[] cardID_18_chars = cardID_18.toCharArray();if (null != cardID_18_chars) {int[] iCard = convertCharToInt(cardID_18_chars);int iSum17 = getPowerSum(iCard);// 获取校验位String checksumString = getCheckCode18(iSum17);if (checksumString.length() > 0) {cardID_18 += checksumString;} else {return null;}}return cardID_18;}/**** @author 作 者:chenyunliang* @note 实现功能:* @note 此方法实现将power和值与11取模获得余数进行校验码判断功能*/private String getCheckCode18(int iSum) {String sCode = "";switch (iSum % 11) {case 10:sCode = "2";break;case 9:sCode = "3";break;case 8:sCode = "4";break;case 7:sCode = "5";break;case 6:sCode = "6";break;case 5:sCode = "7";break;case 4:sCode = "8";break;case 3:sCode = "9";break;case 2:sCode = "x";break;case 1:sCode = "0";break;case 0:sCode = "1";break;}return sCode;}/**** @author 作 者:chenyunliang* @note 实现功能:* @note 此方法实现 将身份证的每位和对应位的加权因子相乘之后,再得到和值 功能*/private int getPowerSum(int[] iArr) {int iSum = 0;if (power.length == iArr.length) {for (int i = 0; i < iArr.length; i++) {for (int j = 0; j < power.length; j++) {if (i == j) {iSum = iSum + iArr[i] * power[j];}}}}return iSum;}/**** @author 作 者:chenyunliang* @note 实现功能:* @note 此方法实现 将字符数组转换成数字数组 功能*/private int[] convertCharToInt(char[] ca) {int len = ca.length;int[] iArr = new int[len];try {for (int i = 0; i < len; i++) {iArr[i] = Integer.parseInt(String.valueOf(ca[i]));}} catch (NumberFormatException e) {e.printStackTrace();}return iArr;}/***** @author 作 者:chenyunliang* @note 实现功能:* @note 此方法实现检查是否是数字功能*/private boolean isNum(String val) {return val == null || "".equals(val) ? false : val.matches("^[0-9]*{1}");}}


登陆认证,参考不同大数据平台的各自认证方法,如果是kerberos认证就使用 kinit xxxx。
hdfs dfs -mkdir /user/hive/udflib
hdfs dfs -put hive-udf.jar /user/hive/udflib
add jar hdfs:///user/hive/udflib/hive-udf.jar;create function dcf.validateidcardudf as 'com.audaque.gldm.ValidateIDCardUDF' using jar 'hdfs:///user/hive/udflib/hive-udf.jar';
在beeline中通过下面语句使用:
select dcf.validateIDCardUDF('370725881105149');

当需要替换jar包,或者不需要函数时,可以删除函数并清理jar包
drop function if exists dcf.validateIDCardUDF;
list jars;

delete jar /opt/huawei/Bigdata/tmp/hivelocaltmp/session_resources/c03ed7ff-1b7b-43e3-b9cc-e76f45b7d397_resources/hive-udf.jar;
文章转载自大数据架构之道,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




