Hive中需要根据需求自定义UDF函数,以自定义函数 my_len (将传入基本数据类型的参数转化为字符串,输出字符串的长度)
hive(default)> select my_len("abcd");
4
1)创建一个Maven工程Hive
2)导入依赖
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
3)创建一个类,继承GenericUDF,实现三个抽象方法。
package com.lasting.study.udf;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
/**
* @author yhm
* @create 2020-08-21 10:07
*/
public class My_len extends GenericUDF {
/**
* 输入类型的鉴别区
*
* @param arguments
* @return 返回值类型的鉴别区对象
* @throws UDFArgumentException 传入参数错误
*/
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
//判断参数的个数
if (arguments.length != 1){
throw new UDFArgumentLengthException("inter one arg please");
}
//判断输入参数的类型
if (!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)){
throw new UDFArgumentTypeException(0,"input first arg type error");
}
return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
}
/**
* 函数逻辑处理
* @param arguments
* @return
* @throws HiveException
*/
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
if (arguments[0].get() == null){
return 0;
}
return arguments[0].get().toString().length();
}
/**
* 返回信息
* @param strings
* @return
*/
@Override
public String getDisplayString(String[] strings) {
return "";
}
}
initialize()用于判断输入类型是否满足要求。
evaluate()逻辑处理方法。
getDisplayString()返回的参数信息,返回空字符串即可:
return"";
随后打成jar包:
4)创建永久函数
(1)在$HIVE_HOME
下面创建auxlib目录
[user1@hadoop102 hive]$ mkdir auxlib
(2)将jar包上传到$HIVE_HOME/auxlib下,然后重启hive
(3)创建永久函数
hive (default)> create function my_len2 as "com.atguigu.hive.MyStringLength";
(4)即可在hql中使用自定义的永久函数
hive (default)> select ename,my_len2(ename) ename_len from emp;
(5)删除永久函数
hive (default)> drop function my_len2;
注意:永久函数跟会话没有关系,创建函数的会话断了以后,其他会话也可以使用。
永久函数创建的时候,在函数名之前需要自己加上库名,如果不指定库名的话,会默认把当前库的库名给加上。
永久函数使用的时候,需要在指定的库里面操作,或者在其他库里面使用的话加上 库名.函数名