编写UDF函数
- (1)创建项目:
- (2)导入依赖:
- (3)继承UDF类
- (4)业务代码
- (5)打包编译
- (5)添加到hive类路径
- (6)创建临时函数
- (7)使用测试
Hive 自带了一些函数,比如:max/min 等,但是数量有限,自己可以通过自定义 UDF 来 方便的扩展。
2)当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义 函数(UDF:user-defined function)。
3)根据用户自定义函数类别分为以下三种:
(1)UDF(User-Defined-Function) 一进一出
(2)UDAF(User-Defined Aggregation Function) 聚集函数,多进一出 类似于:count/max/min
(3)UDTF(User-Defined Table-Generating Functions) 一进多出
如 lateral view explode()
接下来我们自己动手编写一个UDF函数:
(1)创建项目:
启动IDEA,创建MAVEN项目,命名为:com.atguigu,删除src模块,自己创建一个模块,在项目上右键New Module,生成子父模块,名字叫做hive-demo,接着创建packet:com.atguigu.udf:创建MyUDF类:
(2)导入依赖:
点进子模块hive-demo的pom.xml的文件,添加hive的依赖:
<artifactId>hive-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 声明并引入,所有子模块都会自动引入该依赖-->
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
总的依赖如图所示:
<?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">
<parent>
<artifactId>project-200821</artifactId>
<groupId>com.atguigu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hive-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 声明并引入,所有子模块都会自动引入该依赖-->
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
</project>
(3)继承UDF类
在创建好的MyUDF类中,继承GenericUDF,同时实现方法:
package com.atguigu.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;
public class MyUDF extends GenericUDF {
public ObjectInspector initialize(ObjectInspector[] objectInspectors) throws UDFArgumentException {
return null;
}
public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
return null;
}
public String getDisplayString(String[] strings) {
return null;
}
}
这里面有三个方法,一个是初始化,一个是执行计算,最后一个方法是返回一个strung,其中,最后一个方法的意思是去获取执行计划的顺序,一般就返回一个" "就行.
(4)业务代码
编写求字符串长度的代码:
package com.atguigu.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;
public class MyUDF extends GenericUDF {
//合法性校验
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if(arguments.length!=1){
throw new UDFArgumentException("参数个数不为1");
}
return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
}
//处理数据
public Object evaluate(DeferredObject[] arguments) throws HiveException {
String input = arguments[0].get().toString();
if(input==null){
return 0;
}
return input.length();
}
public String getDisplayString(String[] children) {
return "";
}
}
(5)打包编译
编写好,点击Maven,packet打包:
出现下面的界面,build success:
找到jar包的位置:
将打包好的jar包拖到hive安装目录下的lib目录当中,期间遇到错误,传输失败,查看说明permission is not allowed,权限不够,于是我把hive下面的lib目录直接改成chmod 777 lib:
(5)添加到hive类路径
将jar包添加到hive的classpath:
hive (default)> add jar /opt/module/hive/lib/hive-demo-1.0-SNAPSHOT.jar;
Added [/opt/module/hive/lib/hive-demo-1.0-SNAPSHOT.jar] to class path
Added resources: [/opt/module/hive/lib/hive-demo-1.0-SNAPSHOT.jar]
(6)创建临时函数
创建临时函数与开发好的java class进行关联:
hive (default)> create temporary function my_len as "com.atguigu.udf.MyUDF";
OK
Time taken: 0.271 seconds
(7)使用测试
使用udf函数:
hive (default)> select my_len('zhang') ;
OK
_c0
5
Time taken: 0.229 seconds, Fetched: 1 row(s)
hive (default)> select my_len('') ;
OK
_c0
0
Time taken: 0.335 seconds, Fetched: 1 row(s)
这样的话,就求出了我们的字符串的长度。