hive UDF函数

第一章 自定义函数类别

1.1 UDF(User-Defined-Function)

一进一出。

1.2 UDAF(User-Defined Aggregation Function)

用户自定义聚合函数,多进一出。类似于count/max/min

1.3 UDTF(User-Defined Table-Generating Functions)

用户自定义表生成函数,一进多出。如lateral view explode()

第二章 操作

自定义一个UDF实现计算给定基本数据类型的长度,实现

sql 复制代码
select my_len("abcd"); --4

2.1 创建一个 Maven 工程 Hive

2.2 导入依赖(hive版本根据生产具体的版本)

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-exec</artifactId>
        <version>3.1.3</version>
    </dependency>
</dependencies>

2.3 创建一个类(实现三个抽象方法)

java 复制代码
package com.kgl.hive.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.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

/**
 * 自定义Hive UDF:计算输入字符串的长度
 * 仅支持String类型参数,逻辑清晰、类型校验完善,便于在Hive SQL中直接调用
 */
public class my_length extends GenericUDF {

    /**
     * 初始化方法:校验输入参数、确定返回值类型
     * @param objectInspectors输入参数的ObjectInspector数组
     * @return 返回值的ObjectInspector(固定为Java Int类型)
     * @throws UDFArgumentException参数校验不通过时抛出异常
     */
    @Override
    public ObjectInspector initialize(ObjectInspector[] objectInspectors) throws UDFArgumentException {
        // 1. 校验参数数量:必须为1个
        if (objectInspectors.length != 1) {
            throw new UDFArgumentException("自定义函数MyLength仅支持1个参数,实际传入:" + objectInspectors.length);
        }

        // 2. 提取第一个参数的ObjectInspector
        ObjectInspector inspector = objectInspectors[0];

        // 3. 校验参数类型:必须是基本类型(Primitive)
        if (inspector.getCategory() != ObjectInspector.Category.PRIMITIVE) {
            throw new UDFArgumentException("参数必须是基本类型(Primitive),实际类型:" + inspector.getCategory());
        }

        // 4. 强转为PrimitiveObjectInspector,校验具体类型是否为STRING
        PrimitiveObjectInspector primitiveInspector = (PrimitiveObjectInspector) inspector;
        if (primitiveInspector.getPrimitiveCategory() != PrimitiveCategory.STRING) {
            throw new UDFArgumentException("参数必须是字符串(STRING)类型,实际类型:" + primitiveInspector.getPrimitiveCategory());
        }

        // 5. 返回值固定为int类型,直接使用工厂类生成
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector; //由于是计算长度,需要数字,所以工厂类返回的是int
        //return PrimitiveObjectInspectorFactory.javaStringObjectInspector; //如果是转大写,那就是字符串String
    }

    /**
     * 核心计算方法:处理输入参数,返回字符串长度
     * @param deferredObjects延迟加载的输入参数对象数组
     * @return 字符串长度(int类型),null输入返回0
     * @throws HiveException Hive执行异常时抛出
     */
    @Override
    public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
        // 1. 提取第一个(也是唯一的)参数
        DeferredObject deferredObj = deferredObjects[0];
        Object inputObj = deferredObj.get();

        // 2. 处理 null 输入:直接返回 0
        if (inputObj == null) {
            return 0;
        }

        // 3. 非 null 时转为字符串计算长度
        return inputObj.toString().length(); //由于是计算长度,返回的是int
        //return inputObj.toString().toUpperCase(); //如果是转大写,那就是字符串String
    }

    /**
     * 函数描述方法:用于Hive命令行显示函数信息
     * @param strings函数参数描述(这里未用到,保持规范实现)
     * @return函数简洁描述
     */
    @Override
    public String getDisplayString(String[] strings) {
        return "MyLength(STR_COL)-计算字符串长度,仅支持字符串类型参数";
    }
}

2.4 创建临时函数

2.4.1 打成jar包上传到服务器/opt/module/hive/datas/架包名.jar

2.4.2 将jar包添加到hive的classpath,临时生效

sql 复制代码
hive (default)>add jar /opt/module/hive/datas/架包名.jar;

2.4.3 创建临时函数与开发好的java class关联

sql 复制代码
hive (default)> create temporary function my_len as "com.kgl.hive.udf.架包名";

2.4.4 即可在hql中使用自定义的临时函数

sql 复制代码
hive (default)> select ename,my_len(ename) ename_len from emp;

2.4.5 删除临时函数

sql 复制代码
hive (default)> drop temporary function my_len;

注意:临时函数只跟会话有关系,跟库没有关系。只要创建临时函数的会话不断,在当前会话下,任意一个库都可以使用,其他会话全都不能使用。

2.5 创建永久函数

2.5.1 创建永久函数

注意: 因为add jar本身也是临时生效,所以在创建永久函数的时候,需要制定路径(并且因为元数据的原因,这个路径还得是HDFS上的路径)。

sql 复制代码
hive (default)> create function my_len2 as "com.kgl.hive.udf.架包名" using jar "hdfs://hadoop102:8020/udf/架包名.jar";

2.5.2 即可在hql中使用自定义的永久函数

sql 复制代码
hive (default)> select ename,my_len2(ename) ename_len from emp;

2.5.3 删除永久函数

sql 复制代码
hive (default)> drop function my_len2;

注意:永久函数跟会话没有关系,创建函数的会话断了以后,其他会话也可以使用。

永久函数创建的时候,在函数名之前需要自己加上库名,如果不指定库名的话,会默认把当前库的库名给加上。

永久函数使用的时候,需要在指定的库里面操作,或者在其他库里面使用的话加上,库名.函数名。

第三章 IDEA使用

IDE没有加载Maven或者无法创建类

3.1 重新导入Maven项目

3.1.1 在IDEA中打开D:\maven_test\hive-udf\hive-udf目录

3.1.2 找到pom.xml文件

3.1.3 右键点击pom.xml → 选择 "Add as Maven Project" 或"Reload Project"

3.1.4 或者"Maven"→"Reload Project"或"Reimport"(如果右键菜单没有New选项,可能是因为目录没有被识别。

重新加载Maven项目:打开右侧的Maven面板,点击刷新按钮,或者删除.idea文件夹重新导入:关闭IDEA,删除.idea文件夹和*.iml 文件重新用IDEA打开pom.xml)

3.1.5 或者点击右侧Maven工具栏的刷新按钮

3.1.6 使用命令行

xml 复制代码
cd D:/maven_test/hive-udf/hive-udf
mvn clean install

3.2 确保目录标记正确

打开Project Structure(Ctrl + Alt + Shift + S)

检查Modules → 确保src/main/java被标记为Sources(蓝色)

3.3 创建类的正确位置在IDEA的项目视图中:

xml 复制代码
hive-udf
  └── src
      └── main
          └── java
              └── com
                  └── kgl
                      └── [在这里右键]
相关推荐
TTBIGDATA3 小时前
【Ambari Plus】08.Sqoop 安装
大数据·hadoop·ambari·hdp·sqoop·cdh·ambari plus
KASH_SHADOW8 小时前
10-Sqoop的安装与配置
hive·hadoop·sqoop
WhoAmI12 天前
MapReduce框架原理解析一:InputFormat
大数据·hadoop
WhoAmI12 天前
MapReduce框架原理解析三:OutputFormat
大数据·hadoop
WhoAmI12 天前
MapReduce框架原理解析二:Shuffle
大数据·hadoop
王小王-12317 天前
基于 Hive 的网易云音乐数据分析及可视化系统
hive·hadoop·数据分析·音乐数据分析·网易云音乐分析·hive音乐分析·hadoop网易云
极光代码工作室17 天前
基于数据仓库的电商数据分析平台
大数据·hadoop·python·spark·数据可视化
Database_Cool_17 天前
大规模数据分析降本指南:AnalyticDB Serverless 弹性架构实战
数据仓库·阿里云·架构·数据分析·serverless
Database_Cool_17 天前
什么是湖仓一体?和数据仓库的本质区别(附 AnalyticDB MySQL 湖仓一体方案)
数据库·数据仓库·mysql
Chris _data17 天前
WPF 学习第三天 — Modbus RTU 串口通信
hadoop·学习·wpf