描述
- 自定义udf,接收一个字段的每一个value,对应输出转换后的新value,与原value的关系是一对一
依赖
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>${hive.version}</version>
<scope>provided</scope>
</dependency>
如果使用hadoop的writable类型返回,则另需添加依赖:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
<scope>provided</scope>
</dependency>
示例
// 假设处理逻辑为对两个字段的值进行执行四则运算
class MyUDF extends GenericUDF {
// 实现initialize方法,在对所有VALUE进行处理前的参数个数和类型校验; arguments参数是指UDF函数调用时,sql语句中参数列表
override def initialize(arguments: Array[ObjectInspector]): ObjectInspector = {
if (arguments.length != 3) {
throw new UDFArgumentLengthException("arg: column1, column2, calcMethod")
}
// 根据UDF最后返回的值数据类型确定ObjectInspector的类型,通常可以选择java的类型或hadoop writable的类型
PrimitiveObjectInspectorFactory.javaIntObjectInspector
}
// 实现evaluate方法,对每个value进行转换并返回; arguments参数是指UDF函数调用时,table每一行传入的值;返回值需要和initialize的返回类型对齐
override def evaluate(arguments: Array[GenericUDF.DeferredObject]): AnyRef = {
arguments(2).get().toString match {
case "+" => (arguments(0).get().toString.toInt + arguments(1).get().toString.toInt).asInstanceOf[java.lang.Integer]
case "-" => (arguments(0).get().toString.toInt - arguments(1).get().toString.toInt).asInstanceOf[java.lang.Integer]
case "*" => (arguments(0).get().toString.toInt * arguments(1).get().toString.toInt).asInstanceOf[java.lang.Integer]
case "/" => (arguments(0).get().toString.toInt / arguments(1).get().toString.toInt).asInstanceOf[java.lang.Integer]
case o => throw new UDFArgumentException(s"calcMethod should be +, - , * or /, got $o")
}
}
// 实现getDisplayString方法,对UDF进行描述
override def getDisplayString(children: Array[String]): String = {
"I am the plus method for hive"
}
}
部署
临时UDF部署方法:
1. 打成jar包
2. 上传至hive服务器
3. 在hive shell中执行:add jar jar包路径;
4. 在hive shell中执行:create temporary function funtionName as '自定义UDF类路径'
永久UDF部署方法:
1. 打成jar包
2. 上传至hdfs
3. 在hive中进入需要用此UDF的库中,执行:create function funtionName as '自定义UDF类路径' using jar 'jar包的hdfs路径';
删除永久UDF:
1. 在hive中进入需要删除此UDF的库中,执行:drop function funtionName;