文章目录
- Hive自定义标准函数(UDF)
- 继承UDF类或GenericUDF类
- 添加依赖包
- 继承UDF类
- 重写evaluate()方法并实现函数逻辑
- 打包为jar文件编译
- 复制到正确的HDFS路径
- 使用jar创建临时/永久函数
- 创建临时函数并调用
- 创建永久函数并调用
- 总结
Hive自定义标准函数(UDF)
继承UDF类或GenericUDF类
添加依赖包
利用maven添加对应的依赖包,因网络原因,有可能会出现添加不成功的情况,可以将对应的jar包文件夹删除后重写下载,或者更换国内的下载镜像,或者直接从别人哪里拷贝对应的jar,都可以解决依赖包标红的问题
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>1.1.0</version>
</dependency>
继承UDF类
public class TimeDiff extends UDF {
}
重写evaluate()方法并实现函数逻辑
可以利用@Description的方式添加注释,这样打完jar包之后,在hive内可以对应查看到注释内容,常规的注释只能在java环境内才能看到,hive只能用@Description的方式才可以
@Description(
name = "timeDiff",
value = "_FUNC_(dataStr,dataStr,diffType) -"+
"diffType:0:date;1:hour;2:minute;3:second;"+
"4:year;5:month"+"result:"+
"while 0 is date_diff ...",
extended = "select timeDiff('2021-04-06 12:00:00','2021-04-05 23:00:00',1);"+
"result is '13 hour'"
)
public class TimeDiff extends UDF {
public Text evaluate(Text dataStr1, Text dataStr2, IntWritable diffType) throws ParseException {
String s1 = dataStr1.toString();
String s2 = dataStr2.toString();
int type = diffType.get();
//把字符串转成date型
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = sdf.parse(s1);
Date d2 =sdf.parse(s2);
long diff = Math.abs(d1.getTime() - d2.getTime());
long result=0;
String dateType="";
switch (type){
case 0:result=diff/1000/3600/24;
dateType="day";
break;
case 1:result=diff/1000/3600;
dateType="hour";
break;
case 2:result=diff/1000/60;
dateType="minute";
break;
case 3:result=diff/1000;
dateType="second";
break;
case 4:result=diff/1000/3600/24/365;
dateType="year";
break;
case 5:result=diff/1000/3600/24/30;
dateType="month";
break;
}
return new Text(result+" "+dateType);
}
}
打包为jar文件编译
打jar包的方式跟以往的方式有所不同,需要在Terminal 内输入mvn clean 命令先清空文件,然后再用 mvn install 命令来生成jar包
提示build success 之后 表示jar包生成成功
在taeget内可以找到对应的jar包文件,找到后上传到linux系统内,供hive使用
复制到正确的HDFS路径
在hdfs内新建一个文件夹用来存放jar包,并且把刚上传到linux系统内的jar包再次上传到hdfs刚刚新建的文件夹内
hdfs dfs -mkdir /jars/
hdfs dfs -put /hivedata/20210406-hiveudf-1.0-SNAPSHOT.jar /jars/
使用jar创建临时/永久函数
创建临时函数并调用
将jar包上传到linux系统内,就可以直接创建临时函数了,临时函数一旦退出hive则失效,本次测试的功能为将小写转为大写
hive环境下输入命令:
hive> add jar /hivedata/20210406-hiveudf-1.0-SNAPSHOT.jar; --加载jar包
Added [/hivedata/20210406-hiveudf-1.0-SNAPSHOT.jar] to class path
Added resources: [/hivedata/20210406-hiveudf-1.0-SNAPSHOT.jar]
hive> list jars; --查看已加载的jar包
/hivedata/20210406-hiveudf-1.0-SNAPSHOT.jar
hive> create temporary function upstr as 'cn.kgc.kb11.TestUpper'; --创建临时函数
OK
Time taken: 0.005 seconds
hive> select upstr('abcdsgsdfgdfgsdfgsdga'); --调用临时函数
OK
_c0
ABCDSGSDFGDFGSDFGSDGA
Time taken: 0.036 seconds, Fetched: 1 row(s)
创建永久函数并调用
永久函数的调用依赖于hdfs上面的jar包,只要hdfs上对应路径的jar包文件一直存在,则函数就不会失效,下面介绍使用方法
hive> create function timeDiff as 'cn.kgc.kb11.udf.TimeDiff'
> using jar 'hdfs:///jars/20210406-hiveudf-1.0-SNAPSHOT.jar'; --根据hdfs上面的路径加载jar包
converting to local hdfs:///jars/20210406-hiveudf-1.0-SNAPSHOT.jar
Added [/tmp/5fafde50-5795-468a-a089-2501576d6c57_resources/20210406-hiveudf-1.0-SNAPSHOT.jar] to class path
Added resources: [hdfs:///jars/20210406-hiveudf-1.0-SNAPSHOT.jar]
OK
Time taken: 0.139 seconds
hive> desc function timeDiff; --查询jar包内的注释内容
OK
tab_name
timeDiff(dataStr,dataStr,diffType) -diffType:0:date;1:hour;2:minute;3:second;4:year;5:monthresult:while 0 is date_diff ...
Time taken: 0.1 seconds, Fetched: 1 row(s)
hive> desc function extended timeDiff; --查询jar包内注释内容中的extended内容
OK
tab_name
timeDiff(dataStr,dataStr,diffType) -diffType:0:date;1:hour;2:minute;3:second;4:year;5:monthresult:while 0 is date_diff ...
Synonyms: emp.timediff
select timeDiff('2021-04-06 12:00:00','2021-04-05 23:00:00',1);result is '13 hour'
Time taken: 0.006 seconds, Fetched: 3 row(s)
hive> select timeDiff("2021-04-06 12:56:33","2023-05-06 11:24:22",1); --调用函数计算时间差
OK
_c0
18238 hour
Time taken: 0.27 seconds, Fetched: 1 row(s)
总结
UDF函数其实就是一个简单的函数,执行过程就是在Hive转换成mapreduce程序后,执行java方法,类似于像Mapreduce执行过程中加入一个插件,方便扩展. UDF只能实现一进一出的操作,如果需要实现多进一出,则需要实现UDAF .
Hive可以允许用户编写自己定义的函数UDF,来在查询中使用。