@ TOC
在idea中编写函数
创建一个空的maven项目
添加依赖
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>org.pentaho</groupId>
<artifactId>pentaho-aggdesigner-algorithm</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
UDP函数
package hive.function.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
/**
* UDF函数:实现的是一进一出的自定义函数
*
* 1.继承UDF函数类
* 2.重写evaluate()执行方法,在此方法中实现UDF函数
*
*
* 实现需求:将输入的字符串中的小写字母通过UDF函数处理,输出成大写字母
*
*/
public class MyUDF extends UDF {
public String evaluate(String inputStr){
//定义转换后的字符串
String castStr=null;
//判断字符串是否为空
if(inputStr!=null){
//调用String类型中的toUpperCase方法转换大写
castStr=inputStr.toUpperCase();
}
return castStr;
}
public static void main(String[] args) {
//调用UDF方法
String result=new MyUDF().evaluate("hello");
System.out.println(result);
}
}
UDAF函数
package hive.function.udaf;
import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;
/**
* UDAF:实现多进一出的自定义函数
*
*
* 需求实现:获取int类型中的最大值,类似于max()
*/
public class MyUDAF extends UDAF {
//定义静态内部类 实现UDAF函数
public static class GetMaxValue implements UDAFEvaluator{
//创建中间状态
private IntWritable result;
//初始化函数
@Override
public void init() {
//对中间状态进行初始化 首先设为空
result = null;
}
//进行迭代计算
public boolean iterate(IntWritable value){
//如果传入的数据为空 直接停止迭代计算
if(value == null){
return true;
}
//判断中间状态
if(result==null){
//如果中间状态为空 则把第一条数据的值赋值给中间状态
result=new IntWritable(value.get());
}else {
//如果中间状态的值不为空 则比较中间状态和输入的数据哪个值更大 将更大的值赋值给中间状态
result.set(Math.max(result.get(),value.get()));
}
return true;
}
//返回中间状态
public IntWritable terminatePartial(){
return result;
}
//进行聚合计算
public boolean merge(IntWritable otherValue){
return iterate(otherValue);
}
//返回最终的结果
public IntWritable terminate(){
return result;
}
}
}
UDTF函数
package hive.function.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.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import java.util.ArrayList;
/**
* UDTF函数:一进多出的自定义函数
*
* 实现需求:解析k1:v1;k2:v2;k3:v3字符串,转换成为k1 v1,k2 v2,k3 v3这样的三行数据
*
*/
public class MyUDTF extends GenericUDTF {
@Override
public StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException {
//判断传入的参数
if (argOIs.length != 1) {
throw new UDFArgumentException("初始化方法中只能传入一个参数");
}
//定义列名集合
ArrayList<String> fieldNameList = new ArrayList<>();
//定义列的集合
ArrayList<ObjectInspector> fieldList = new ArrayList<>();
//进行赋值
fieldNameList.add("key");
fieldList.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
fieldNameList.add("value");
fieldList.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNameList, fieldList);
}
//主要的UDTF函数实现
@Override
public void process(Object[] args) throws HiveException {
//获取要处理的数据
String line=args[0].toString();
//根据分隔符;对数据进行拆分
String[] splitLine=line.split(";");
//进行遍历
for(String s:splitLine){
//再根据分隔符:进行拆分
String[] split=s.split(":");
//将数据进行传输
forward(split);
}
}
@Override
public void close() throws HiveException {
}
}
使用maven的package功能将代码打成jar包
导入虚拟机
Hive中注册自定义函数
上传jar包到/opt/jar目录下
在hive命令行或者beeline命令行中添加jar包
add jar jar包的本地路径;
add jar /opt/jar/hive_udf_function.jar;
临时注册
特点:
1.当前session有效
2.对于所有的数据库都是可用的
-- create temporary function 自定义函数名 as '自定义函数的全包路径';
create temporary function MyUDF as 'hive.function.udf.MyUDF';
-- 调用自定义函数
select MyUDF('abcdefg');