HIVE函数讲解之自定义函数

当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。

根据用户自定义函数类别分为以下三种:

UDF(User-Defined-Function)一进一出。

UDAF(User-Defined Aggregation Function)用户自定义聚合函数,多进一出。

UDTF(User-Defined Table-Generating Functions)用户自定义表生成函数,一进多出。

聚合函数 UDAF 能够满足我们使用的基本都已经内置了,本文就重点介绍一下UDF和UDTF函数的实现。

一、定义要求

1. 继承Hive提供的类

org.apache.hadoop.hive.ql.udf.generic.GenericUDF;

org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;

2. 实现类中的抽象方法

UDF函数类

public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {

}

public Object evaluate(DeferredObject[] arguments) throws HiveException {

}

public String getDisplayString(String[] children) {

}

UDTF函数类

@Override

public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {

}

public void process(Object[] args) throws HiveException {

}

public void close() throws HiveException {

}

3. 在Hive的命令行窗口创建函数

① 添加打包上传的jar包。

add jar linux_jar_path

② 创建Funcation。

create [temporary] function [dbname.]function_name AS class_name;

③ 删除函数

drop [temporary] function [if exists】[dbname.]function_name;

 

二、实现UDF函数

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

select my_len("abcd");4

1. 创建Maven工程,导入依赖

<dependencies><dependency><groupId>org.apache.hive</groupId>、

<artifactId>hive-exec</artifactId>

<version>3.1.3</version>

</dependency></dependencies>

2. 创建函数类实现GenericUDF类

package com.atguigu;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;

import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;

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 LengthUDFTest extends GenericUDF {

//initialize方法,全局执行一次(一般做一些校验)

@Override

public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {

// 判断输入参数的个数

if (arguments.length != 1) {

throw new UDFArgumentException("输入参数长度异常,只允许输入1个参数");

}

// 判断输入参数的类型(是否是基本类型)

// Category 共定义了5种类型:基本类型(Primitive),集合(List),键值对映射(Map),结构体(Struct),联合体(Union)

if(!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)){

throw new UDFArgumentTypeException(0,"输入参数类型异常");

}

// 函数本身返回值为 int,需要返回 int 类型的鉴别器对象

return PrimitiveObjectInspectorFactory.javaIntObjectInspector;

}

//evaluate方法,函数的逻辑处理方法,进来一条执行一次

@Override

public Object evaluate(DeferredObject[] arguments) throws HiveException {

if (arguments[0].get() == null) {

return 0;

} else {

return arguments[0].get().toString().length();

}

}

//getDisplayString 方法,在使用explain 查看SQL执行计划时,会显示(一般直接返回null即可)

@Override

public String getDisplayString(String[] strings) {

return null;

}

}

三、实现UDTF函数

自定义UDTF函数实现按照分隔符切割字符串,变成多个单词。

1. 创建Mvaen工程,导入依赖

2. 创建函数类实现GenericUDTF类

package com.atguigu;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;

import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;

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 SplitUDTFTest extends GenericUDF {

//initialize方法,全局执行一次(一般做一些校验)

@Override

public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {

// 判断输入参数的个数

if (arguments.length != 1) {

throw new UDFArgumentException("输入参数长度异常,只允许输入1个参数");

}

// 判断输入参数的类型(是否是基本类型)

// Category 共定义了5种类型:基本类型(Primitive),集合(List),键值对映射(Map),结构体(Struct),联合体(Union)

if(!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)){

throw new UDFArgumentTypeException(0,"输入参数类型异常");

}

// 函数本身返回值为 int,需要返回 int 类型的鉴别器对象

return PrimitiveObjectInspectorFactory.javaIntObjectInspector;

}

//evaluate方法,函数的逻辑处理方法,进来一条执行一次

@Override

public Object evaluate(DeferredObject[] arguments) throws HiveException {

if (arguments[0].get() == null) {

return 0;

} else {

return arguments[0].get().toString().length();

}

}

//getDisplayString 方法,在使用explain 查看SQL执行计划时,会显示(一般直接返回null即可)

@Override

public String getDisplayString(String[] strings) {

return null;

}

}

四、自定义函数的使用

UDF函数和UDTF函数的使用一样,测试一下自定义的UDF。

1. 临时函数

①打成jar包上传到服务器/hive/datas/myudf.jar。

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

add jar /hive/datas/myudf.jar;

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

create temporary function my_len as "com.atguigu.LengthUDFTest";

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

select ename, my_len(ename) ename_lenfrom emp;

⑤删除临时函数

drop temporary function my_len;

注意:

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

2. 永久函数

①创建永久函数

注意:

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

create function my_len2 as "hive.udf.MyUDF" using jar "hdfs://hadoop:8020/udf/myudf.jar";

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

select ename, my_len2(ename) ename_lenfrom emp;

③删除永久函数。

drop function my_len2;

注意:

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

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

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

五、总结

本文讲解了HIVE的自定义函数的实现步骤,实现了一个简单的计算给定基本数据类型的长度的UDF函数,其余的两种函数自定义需要大家去操作体验。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用自定义UDF函数的方式实现Hive中的CAST函数,需要按照以下步骤进行操作: 1. 创建一个自定义UDF函数类,该类需要继承Hive中的GenericUDF或者AbstractGenericUDF类。具体而言,如果你需要处理单个参数,则可以继承GenericUDF类,如果需要处理多个参数,则可以继承AbstractGenericUDF类。 2. 在类中实现evaluate()方法,该方法用于实现CAST函数的逻辑。该方法需要接收参数,并返回转换后的值。在方法中,你需要编写实现将传入参数转换成指定类型的代码。具体而言,你可以使用Java中的类型转换操作或者其他相关的转换函数来完成这个过程。 3. 将该类编译打包成jar文件,并上传到Hive的classpath中。 4. 在Hive中注册该自定义UDF函数。具体而言,你需要使用CREATE FUNCTION语句来创建该函数,并指定函数的名称、参数类型、返回类型等信息。例如,以下是一个示例代码: ``` CREATE FUNCTION my_cast AS 'com.example.MyCastUDF' USING JAR 'path/to/my-cast-udf.jar'; ``` 5. 在Hive中使用该自定义UDF函数。具体而言,你需要在SELECT语句中调用该函数,并将需要转换的参数作为函数的参数传入。例如,以下是一个示例代码: ``` SELECT my_cast(column_name AS target_type) FROM table_name; ``` 注意,这里的column_name是需要转换的列名,target_type是需要转换成的目标类型。你需要根据具体的情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值