UDF api:
https://hive.apache.org/javadocs/r1.2.2/api/org/apache/hadoop/hive/ql/exec/UDF.html
Hive的用户定义函数需要继承UDF类,实现evaluate方法(一个或多个);该方法由hive调用。
Hive解析要调用的方法的确切方式可以通过设置自定义UDFMethodResolver来配置(传入构造器);
定义的UDF类会在每个JVM中实例化出一个实例,并且不会被并发调用。
evaluate方法的返回类型以及方法参数可以是Java原语或相应的Writable类。理论上evaluate不应该返回null值,但是可以把方法设为void。
package hiveudf;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
//Description注解部分提供函数的帮助信息.
@Description(name = "DateToWeek", value = "_FUNC_(date) - Convert yyyyMMdd to yyyyWww.")
public class UDFtime extends UDF {
// evaluate方法的输入输出即是UDF函数的输入输出.
public String evaluate(String date) {
StringBuilder sb = new StringBuilder();
int year = Integer.parseInt(date.substring(0, 4));
int mon = Integer.parseInt(date.substring(4, 6));
int day = Integer.parseInt(date.substring(6, 8));
boolean ry = false;
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
ry = true;
if (ry) {
for (int i = 1; i < mon; i++) {
day += montoday_r[i];
}
} else {
for (int i = 1; i < mon; i++) {
day += montoday[i];
}
}
int week = day / 7;
if (day % 7 != 0)
week++;
sb.append(year);
sb.append('W');
if (week < 10)
sb.append(0).append(week);
else
sb.append(week);
return sb.toString();
}
int[] montoday = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// 闰年
int[] montoday_r = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
}
部署方法:
在hdfs中上传jar包;
在hive中添加function:
- 创建临时function
CREATE TEMPORARY FUNCTION datetoweek as 'hiveudf.UDFtime' using jar 'hdfs:///user/jar/hiveUDF/UDFtime.jar'
临时function 只在当前会话中有效,退出就会失效,每次打开都需要添加;同时临时function不能指定数据库
- 创建永久function
CREATE FUNCTION [db_name.]function_name AS class_name
[USING JAR|FILE|ARCHIVE 'file_uri' [, JAR|FILE|ARCHIVE 'file_uri'] ];
CREATE FUNCTION default.datetoweek as 'hiveUDF.UDFtime' using jar 'hdfs:///user/jar/hiveUDF/UDFtime.jar'
永久function会一直生效,且需要为函数指定数据库;
参考:https://blog.youkuaiyun.com/liam08/article/details/51311772