- hive的自定义函数大致可以分为三种
UDF (User-Defined-Function):一进一出
UDAF (User-Defined Aggregation Function):多进一处,类型于聚合函数
UDTF (User-Defined Table-Generating Functions):一进多出
自定义UDF函数
编写一个函数。会将输入的数字加上5然后输出
import org.apache.hadoop.hive.ql.exec.UDF;
public class myUDF extends UDF {
public int evaluate(int data) {
return data + 5;
}
}
- 注意事项
自定义的UDF函数类必须继承UDF类
自定义的UDF函数必须实现evaluate方法
自定义的UDF函数的evaluate必须有返回值,返回值是null也可以,但是必须要有
自定义的UDF函数的evaluate方法可以重载 - 自定义函数的使用
将jar包导入hive中:add jar /home/hive-1.0-SNAPSHOT.jar
创建函数:create function hive.addFive as 'Hive.myUDF'
注意:函数在创建的时候可以指定数据库,不指定的话,默认就是当前数据库,自定义函数不可以跨库使用 - 自定义函数的使用
自定义UDTF函数
定义一个可以将任意分割符切割成独立的单词
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import java.util.ArrayList;
import java.util.List;
public class myUDTF extends GenericUDTF {
private List<String>dataList = new ArrayList<>();
/**
* 初始化方法
*
* @param argOIs
* @return
* @throws UDFArgumentException
*/
@Override
public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
//炸裂,这是集合,说明炸裂可以分成多个列
List<String> fieldNames = new ArrayList<>();
//将字段起别名为word
fieldNames.add("word");
//这存储的是这列的数据类型,这个数据类型是和数据有关
List<ObjectInspector> fieldOIs = new ArrayList<>();
fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
//这里是输出的字段名还有数据类型,不写的话有别名,并且这个字段名可以被覆盖
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
}
/**
* 处理数据,按行来
*
* @param objects
* @throws HiveException
*/
@Override
public void process(Object[] objects) throws HiveException {
//接受的是个数组
//获取数据
String data = objects[0].toString();
//获取分割符
String splitKey = objects[1].toString();
//切分数据
String[] words = data.split(splitKey);
//写出数据
for (String word : words) {
//数据集合清空
dataList.clear();
//遍历写出每一个分割后的数据
//因为上出的列是集合,数据类型要匹配,这里写出的也应该是集合
dataList.add(word);
forward(dataList);
}
}
@Override
public void close() throws HiveException {
}
}
- 注意点
自定义UDTF有三个方法:initialize、process、close
initialize:初始化方法,用来定义字段名,和字段的数据类型,或者来判断输入的参数是否符合要求
process:用来处理数据,一行一行的读取数据
close:用来关闭资源 - 操作练习