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
                      └── [在这里右键]
相关推荐
暴躁小师兄数据学院1 天前
【AI大数据工程师特训笔记】第15讲:大数据环境安装
大数据·hadoop·flink·spark
王小王-1231 天前
基于 Hadoop + Flask 的电动汽车数据分析与可视化系统设计与实现
hadoop·数据分析·flask·电动汽车·新能源汽车数据分析·新能源汽车销量分析·新能源汽车销售分析
云器科技1 天前
螳螂科技:从组装到统一,如何用云器 Lakehouse 完美替代“MC+DW+ADB”三件套?
数据库·数据仓库·人工智能
王小王-1231 天前
基于机器学习与Hadoop的心脏病数据分析与可视化设计与实现
hadoop·机器学习·数据分析·心脏病预测
知识分享小能手1 天前
Hadoop学习教程,从入门到精通, Hadoop 3.x 高可用集群 — 知识点详解(6)
大数据·hadoop·学习
王小王-1232 天前
基于商品评价的评论情感分析与可视化系统
hive·情感分析·商品评价分析·主题分析·商品评论分析
知识分享小能手2 天前
Hadoop学习教程,从入门到精通, ZooKeeper 分布式协调服务 — 全面知识点与案例代码(5)
hadoop·分布式·zookeeper
Nefu_lyh2 天前
【Hive】 八、Hive 计算引擎:MapReduce / Tez / Spark 对比与选型
hive·spark·mapreduce
知识分享小能手3 天前
Hadoop学习教程,从入门到精通, MapReduce分布式计算框架 — 完整知识点与代码案例(4)
hadoop·学习·mapreduce