一行输入,返回一个结果
可以满足日常工作中的大部分需求
UDF的实现方法
Hive 提供了两个实现 UDF 的方式:
第一种:继承 UDF 类
- 优点:
- 实现简单
- 支持Hive的基本类型、数组和Map
- 支持函数重载
- 缺点:
- 逻辑较为简单,只适合用于实现简单的函数
这种方式编码少,代码逻辑清晰,可以快速实现简单的UDF
第二种:继承 GenericUDF 类
- 优点:
- 支持任意长度、任意类型的参数
- 可以根据参数个数和类型实现不同的逻辑
- 可以实现初始化和关闭资源的逻辑(initialize、close)
- 缺点:
- 实现比继承UDF要复杂一些
与继承 UDF 相比,GenericUDF 更加灵活,可以实现更为复杂的函数
关于两者的选择
如果函数具有以下特点,优先继承 UDF 类:
- 逻辑简单,比如英文转小写函数
- 参数和返回值类型简单,都是Hive的基本类型、数组或Map
- 没有初始化或关闭资源的需求
否则考虑继承 GenericUDF 类
接下来介绍这两种实现方式的具体步骤
继承 UDF 类
第一种方式的代码实现最为简单,只需新建一个类 继承UDF,然后编写 evaluate() 即可
import org.apache.hadoop.hive.ql.exec.UDF;
/**
* 继承 org.apache.hadoop.hive.ql.exec.UDF
*/
public class SimpleUDF extends UDF {
/**
* 编写一个函数,要求如下:
* 1. 函数名必须为 evaluate
* 2. 参数和返回值类型可以为:Java基本类型、Java包装类、org.apache.hadoop.io.Writable等类型、List、Map
* 3. 函数一定要有返回值,不能为 void
*/
public int evaluate(int a, int b) {
return a + b;
}
/**
* 支持函数重载
*/
public Integer evaluate(Integer a, Integer b, Integer c) {
if (a == null || b == null || c == null)
return 0;
return a + b + c;
}
}
继承UDF类的方式非常简单,但还有一些需要注意的地方:
- evaluate() 方法并不是继承自 UDF 类(编写代码时名字容易打错,哈哈哈~)
- evaluate() 的返回值类型不能为 void(你这个函数返回值都没有,我要你干嘛?)
支持的参数和返回值类型
支持 hive基本类型、数组和Map
Hive基本类型
Java可以使用Java原始类型、Java包装类或对应的Writable类
PS:对于基本类型,最好不要使用 Java原始类型,当 null 传给 Java原始类型 参数时,UDF 会报错。Java包装类还可以用于null值判断
Hive类型 | Java原始类型 | Java包装类 | hadoop.io.Writable |
---|---|---|---|
tinyint | byte | Byte | ByteWritable |
smallint | short | Short | ShortWritable |
int | int | Integer | IntWritable |
bigint | long | Long | LongWritable |
string | String | - | Text |
boolean | boolean | Boolean | BooleanWritable |
float | float | Float | FloatWritable |
double | double | Double | DoubleWritable |
数组和Map
Hive类型 | Java类型 |
---|---|
array | List |
Map&l |