用户自定义函数简称UDF,源自于英文user-defined function。自定义函数总共有3类,是根据函数输入输出的行数来区分的,分别是:
UDF(User-Defined-Function)普通函数,一进一出
UDAF(User-Defined Aggregation Function)聚合函数,多进一出
UDTF(User-Defined Table-Generating Functions)表生成函数,一进多出
UTF标准分类扩大化:
UDF分类标准可以扩大到Hive的所有函数中:包括内置函数和自定义函数。
UDF函数通常把它叫做普通函数,最大的特点是一进一出,也就是输入一行输出一行。比如round这样的取整函数,接收一行数据,输出的还是一行数据。
UDAF函数通常把它叫做聚合函数,A所代表的单词就是Aggregation聚合的意思。最大的特点是多进一出,也就是输入多行输出一行。比如count、sum这样的函数。
- count:统计检索到的总行数。
- sum:求和
- avg:求平均
- min:最小值
- max:最大值
- 数据收集函数(去重): collect_set(col)
- 数据收集函数(不去重): collect_list(col)
UDTF函数通常把它叫做表生成函数,T所代表的单词是Table-Generating表生成的意思。最大的特点是一进多出,也就是输入一行输出多行。
UDTF函数也是我们接触比较少的函数,比如explode函数
在企业中处理数据的时候,对于敏感数据往往需要进行脱敏处理。比如手机号。我们常见的处理方式是将手机号中间4位进行****处理。
Hive中没有这样的函数可以直接实现功能,虽然可以通过各种函数的嵌套调用最终也能实现,但是效率不高,现要求自定义开发实现Hive函数,满足上述需求。
- <dependencies>
- <dependency>
- <groupId>org.apache.hive</groupId>
- <artifactId>hive-exec</artifactId>
- <version>3.1.2</version>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-common</artifactId>
- <version>3.1.4</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>2.2</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- </excludes>
- </filter>
- </filters>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- package cn.ittest.hive.udf;
-
- import org.apache.commons.lang.StringUtils;
- import org.apache.hadoop.hive.ql.exec.UDF;
-
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
-
- /**
- * @description: hive自定义函数UDF 实现对手机号中间4位进行****加密
- * @author: Itcast
- */
- public class EncryptPhoneNumber extends UDF {
- /**
- * 重载evaluate方法 实现函数的业务逻辑
- * @param phoNum 入参:未加密手机号
- * @return 返回:加密后的手机号字符串
- */
- public String evaluate(String phoNum){
- String encryptPhoNum = null;
- //手机号不为空 并且为11位
- if (StringUtils.isNotEmpty(phoNum) && phoNum.trim().length() == 11 ) {
- //判断数据是否满足中国大陆手机号码规范
- String regex = "^(1[3-9]\\d{9}$)";
- Pattern p = Pattern.compile(regex);
- Matcher m = p.matcher(phoNum);
- if (m.matches()) {//进入这里都是符合手机号规则的
- //使用正则替换 返回加密后数据
- encryptPhoNum = phoNum.trim().replaceAll("()\\d{4}(\\d{4})","$1****$2");
- }else{
- //不符合手机号规则 数据直接原封不动返回
- encryptPhoNum = phoNum;
- }
- }else{
- //不符合11位 数据直接原封不动返回
- encryptPhoNum = phoNum;
- }
- return encryptPhoNum;
- }
- }
把jar包上传到Hiveserver2服务运行所在机器的linux系统,或者HDFS文件系统。
在客户端中使用命令把jar包添加至classpath。