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)

这样的话,就求出了我们的字符串的长度。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐