在进行大数据分析或者开发的时候,难免用到Hive进行数据查询分析,Hive内置很多函数,但是会有一部分需求需要自己开发,这个时候就需要自定义函数了,Hive的自定义函数开发非常方便,今天首先讲一下UDF的入门开发。
简单实现将字符串小写化的功能。
首先Maven创建
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hive.tutorial</groupId>
<artifactId>low-str</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
package com.hive.tutorial.udf;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
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;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
import org.apache.hadoop.io.Text;
/**
* @author panlf
* @date 2024/1/3
*/
public class LowStr extends GenericUDF {
StringObjectInspector stringObjectInspector;
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if(arguments == null || arguments.length != 1){
throw new UDFArgumentException("该方法只接受一个参数");
}
ObjectInspector a = arguments[0];
if (!(a instanceof StringObjectInspector)) {
throw new UDFArgumentException("该方法的参数必须是字符串");
}
//检查通过后,将参数赋值给成员变量ObjectInspector,为了在evaluate()中使用
this.stringObjectInspector = (StringObjectInspector) a;
//用工厂类生成用于表示返回值的ObjectInspector
return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
String v = stringObjectInspector.getPrimitiveJavaObject(arguments[0].get());
return new Text(v.toLowerCase());
}
@Override
public String getDisplayString(String[] children) {
return "将输入的字符串小写化";
}
}
注意很多网上资料其实是继承UDF
这个类的,但是这个类已过时了,建议使用GenericUDF
。
GenericUDF和UDF都是Hive中的用户自定义函数,但两者在处理数据类型和灵活性上有所不同。基础的UDF接口适合于简单的数据类型,如文本、整数等,而复杂的GenericUDF则可以处理更复杂的数据类型,包括Map、List和Set。
具体来说,以下是GenericUDF相对于UDF的优势:
因此,当您需要处理的数据类型比较复杂或需要进行一些特定的初始化和清理操作时,建议使用GenericUDF而不是UDF。
mvn clean package
首先将Jar传到服务器,我是传到服务器的/data/temp_data/
文件夹下
通过HDFS
命令将Jar包传到Hadoop上
> hdfs dfs -put /data/temp_data/low-str-1.0.0.jar /hivejar/hiveudf
运行Hive cli,进入Hive客户端
运行以下命令
hive > add jar hdfs://172.23.39.9:8020/hivejar/hiveudf/low-str-1.0.0.jar;
create temporary function low_str as 'com.hive.tutorial.udf.LowStr';
然后即可使用
select low_str('AAAA');
注意
Hive的UDF临时函数在会话结束时失效
create function sys.low_str as 'com.hive.tutorial.udf.LowStr' using jar 'hdfs://172.23.39.9:8020/hivejar/hiveudf/low-str-1.0.0.jar';
注意sys.low_str
中的sys
代表的是库名,如果没有指定的话,默认是default
drop function low_str;
//查看全部函数
show functions;
### 查看某个函数
describe function low_str;
我在Java的程序中调用该永久函数,发生以下错误,就是无法识别出注册的函数。
我通过查资料发现以下方法可解决(包括且不限于)
default.low_str
)RELOAD FUNCTIONS
,重刷FUNCTIONS
信息