【前言】
- UDF:自定义标准函数(实际使用最多)
- UDAF:自定义聚合函数
- UDTF:自定义表生成函数
一、添加依赖
<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>
【注意:依赖可能飘红,尤其是hive-exec,大家可以将jar包中的hive-exec 文件夹删除再下载,或者更换下载镜像地址】
二、编写UDF代码
逻辑代码
1.UDF
类 extends UDF{
提供一个evaluate()方法,在这里面实现业务功能
}
2.GenericUDF
类 继承 GenericUDF{
init() //初始化,判断参数输入是否合理
evaluate() //业务功能
}
来个例子:计算两个时间的差值,单位有用户选择
package HiveUDF1.udf;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author shall潇
* @Date 2021/4/6
* @Description 计算两个时间之差,根据用户自己选择
*/
@Description(
name = "timeDiff",
value = "_Func_(datestr1,datestr2,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 12:00:00',1);"+
"result is '24 hour'."
)
public class TimeDiff extends UDF {
public Text evaluate(Text datestr1, Text datestr2, IntWritable diffType) throws ParseException {
String s1 = datestr1.toString();
String s2 = datestr2.toString();
int type = diffType.get();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = sdf.parse(s1); //String转换成Date
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);
}
}
三、测试
写好后,先不急着上传,先自己测试一下
按下【ctrl+shift+T】
别忘记勾选
编写测试类
public class TimeDiffTest {
@Test
public void evaluate() throws ParseException {
TimeDiff td = new TimeDiff();
Text evaluate = td.evaluate(new Text("2020-04-05 12:00:00"), new Text("2020-04-05 06:00:00"), new IntWritable(1));
System.out.println(evaluate);
}
}
查看结果
OK!可以打包上传
四、打包置Linux上执行
如果配置了maven的环境变量,可以直接
mvn clean
没有的话,就是写上maven的路径
成功后在 target文件夹下找到对应的jar包
将jar 包拖到Linux上,找个地方放一下,下面你有两个选择
- 临时函数
- 永久函数
1、临时函数
首先启动hive,然后执行
add jar jar包名; //将jar包导入到内存,下次起动就没有了
查看一下是否添加进来
create temporary function 函数名 as '全类名';
成功后就可以直接使用自定义函数了
2、永久函数
其实是只要jar包在HDFS上,就会有,没了也就没了
首先将jar包上传至HDFS上
hdfs dfs -put jar包 HDFS路径
create function 函数名 as '全类名'
using jar 'hdfs:///hivejar/HiveUDF1-1.0-SNAPSHOT.jar';
查看函数
desc function 函数名
UDTF
UDAF
继承 GenericUDAF
iterate(),merge(),terminatePartial(),terminate()
分为四种模式
partial1 : Mapper阶段,调用iterate()和terminatePartial()
partial2 : Combiner阶段,调用merge()和 terminatePartial()
final : reducer阶段,调用merge() 和 terminate()
complete : 只调用Mapper,没有Reducer,调用iterate()和 terminate()