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
                      └── [在这里右键]
相关推荐
卷毛迷你猪3 天前
快速实验篇(A11)数据集成与多维分析:从单实验产出到跨实验宽表
hive·hadoop
西木莉3 天前
数据仓库概述
数据仓库
卷毛迷你猪4 天前
快速实验篇(A10)短序列上 SPI 的失效机制
hadoop
Francek Chen4 天前
【大数据处理与分析】数据仓库Hive:04 数据仓库Hive概述
大数据·数据仓库·hive·hadoop·分布式
Gl�ria4 天前
Hadoop/YARN 集群缩容:下线DN节点
大数据·hadoop·分布式
计算机源码社4 天前
基于大数据技术的台北市住宅价格影响因素挖掘与可视化分析-基于Python与Hadoop的台北市住宅价格数据仓库构建与可视化
大数据·hadoop·python·数据分析·spark·毕业设计·数据可视化
计算机源码社4 天前
基于Hadoop+Spark的乳腺癌病理数据可视化分析系统 基于K-Means聚类与PCA降维的乳腺癌形态特征分析系统
大数据·hadoop·python·数据分析·spark·毕业设计·数据可视化
Moshow郑锴4 天前
从“水库”到“直饮水站”:重新理解 Data Mart 与 Data Lake、Data Lakehouse、Data Warehouse 的区别
数据仓库·data·湖仓一体
躺柒5 天前
读数据架构知识体系指南01关系数据仓库(上)
数据仓库·架构·数据分析·spark·数据湖·关系数据库·企业数据仓库
卷毛迷你猪5 天前
快速实验篇(A9-2)Python vs MapReduce:小批量任务的工具选择
大数据·hadoop