1.背景
我们在写hive sql 的时候经常会用到一些内置的函数,例如:max,min,substr等。当这些函数没有办法满足我们的需求的时候,该怎么办呢?我们可以通过自己写udf函数来实现内置函数无法实现的功能。
2.概述
udf函数,全称是用户自定义函数(user defined function),就是用java 来写一些满足我们需求的函数,并可以在hive sql中使用这些函数。
从功能上看,udf函数可以分为三种:
(1)udf(User defined scalar function):用户自定义标量值函数,输入和输出是一对一的关系,输入一行,输出一行。
(2)udaf(User defined aggregation function): 用户自定义聚合函数,输入和输出是多对一的关系,输入多行,输出一行,功能和聚合函数类似,可以和group by一起使用,和内置函数max,min,sum等类似。
(3)udtf(User defined table function:):用户自定义表值函数,输入和输出是一对多的关系,输入一行,输出多行。是用来解决一次函数调用输出多行数据的场景的。
udf函数编写步骤:
(1)导入相关依赖,继承UDF类,实现evaluate方法。
(2)编写函数。
(3)构建jar包,导入服务器。
(4)hive命令行里,执行add jar和create function命令。
3.实战
引入依赖
compileOnly "org.apache.hadoop:hadoop-common:$hadoopVersion"
compileOnly("org.apache.hive:hive-exec:$hiveVersion")
(1) udf函数
udf
编写udf函数,首先继承org.apache.hadoop.hive.ql.exec.UDF, 实现evaluate()方法,并且可以重载多个该方法,hive调用这个方法来完成数据的处理我们可以调用。这个方法的返回值类型和方法参数类型可以是java基本类型,或者相对应的Writable(org.apache.hadoop.io.Writable)类。
udf函数在执行时是单例模式,每个jvm只有一个实例,并且不会被并发调用。
示例:
package com.share.example.udf;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
import java.util.Arrays;
import java.util.List;
/**
* @Description
* @Date 2020/6/26 10:57 PM
**/
public class HelloUDF extends UDF {
public int evaluate(int a) {
return a + a;
}
public double evaluate(int a, double b) {
return a + b;
}
public String evaluate(String a, int b, Text c) {
return a + b + c;
}
public Text evaluate(String a) {
return new Text(a + a);
}
public String evaluate(List<Integer> a) {
return StringUtils.join(a, "");
}
」
构建jar包,并导入服务器,本地就不用导了,然后在服务器里add jar,和create function.
hive>add jar /Users/kechenxi/Documents/projects/idea_projects/udf-test/out/artifacts/untitled_main_jar/untitled.main.jar;
Added [/Users/kechenxi/Documents/projects/idea_projects/udf-test/out/artifacts/untitled_main_jar/untitled.main.jar] to class path
Added resources: [/Users/kechenxi/Documents/projects/idea_projects/udf-test/out/artifacts/untitled_main_jar/untitled.main.jar]
hive> create temporary function add as 'com.share.example.udf.HelloUDF';
OK
Time taken: 0.014 seconds
使用函数:
hive> select add(1);
OK
2
Time taken: 0.387 seconds, Fetched: 1 row(s)
hive> select add(array(1,2,3));
OK
123
Time taken: 0.233 seconds, Fetched: 1 row(s)
GenericUDF
GenericUDF函数与UDF函数相比的优势:
a.可以接收复杂类型的参数并返回复杂类型的参数,例如可以返回结构体
b.可以接受传入的参数长度可变,即一个evaluate方法,可以传入任意个参数。
c.可以接收某个类型的无限嵌套,例如,array<int>,array<array<int>>...
可以简单的理解为GenericUDF是复杂版的UDF&#x