Hive---自定义函数

文章介绍了如何在Hive中创建自定义函数,包括UDF(一进一出)和UDTF(一进多出)。首先,需要创建一个Maven工程,导入Hive和Hadoop的相关依赖。然后,根据需求编写自定义函数类,分别继承GenericUDF或GenericUDTF。接着,将编译后的jar包上传至服务器,并通过Hive命令行创建临时或永久函数。临时函数在客户端关闭后失效,而永久函数在特定库内持久有效。
摘要由CSDN通过智能技术生成

Hive自定义函数



定义

当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。常用来自定义的是 UDF、UDTF 函数。聚合函数 UDAF 能够满足我们使用的基本都已经内置了。

根据用户自定义函数类别分为以下三种:
(1)UDF(User-Defined-Function):一进一出
(2)UDAF(User-Defined Aggregation Function):聚集函数,多进一出(类似于:count/max/min)
(3)UDTF(User-Defined Table-Generating Functions):一进多出,如 lateral view explode()

官方文档地址
https://cwiki.apache.org/confluence/display/Hive/HivePlugins

自定义函数步骤

创建一个Maven工程,导入依赖

 <dependency>
      <groupId>org.apache.hive</groupId>
      <artifactId>hive-exec</artifactId>
      <version>3.1.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>3.1.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hive</groupId>
      <artifactId>hive-jdbc</artifactId>
      <version>3.1.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hive</groupId>
      <artifactId>hive-jdbc</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.glassfish</groupId>
          <artifactId>javax.el</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-runner</artifactId>
        </exclusion>
      </exclusions>
      <version>3.1.2</version>
    </dependency>

创建自定义函数类

自定义 UDF 函数,创建的类需继承 GenericUDF类,重写方法(org.apache.hadoop.hive.ql.udf.generic.GenericUDF)
自定义 UDTF 函数,创建的类需继承 GenericUDTF类,重写方法(org.apache.hadoop.hive.ql.udf.generic.GenericUDTF)

在 hive 的命令行窗口创建函数

创建函数分为:创建临时函数、创建永久函数 两种

创建函数命令如下:
create [temporary] function [dbname.]function_name AS class_name; 
删除函数命令如下:
drop [temporary] function [if exists] [dbname.]function_name;

创建临时函数

1.将 maven 工程打包后的 jar,添加到 linux 服务器某个目录下
2.使用命令添加 jar,命令为:add jar 目录(jar所在linux目录)
3.创建function,命令:create temporary function 函数名 as 类路径(jar包中自定义函数的类路径)
4.通过命令:show functions可查看自己创建的函数。
5.提示:临时函数,在hive客户端关闭后失效,对 hive 中的全部数据库有效

创建永久函数

1.将 maven 工程打包后的 jar,上传到 hdfs 某个目录下(目录可自定义)
2.创建function,命令:create function ‘库名.函数名’ as ‘类路径’ using jar ‘jar包所在hdfs目录’
3.通过命令:show functions可查看自己创建的函数 (如果函数名不是【库名.函数名】格式,show functions是看不到的)。
4.提示:永久函数,只对当前所在库生效,其他库均不生效,所以建议使用【库名.函数名】命名方式。函数不会因为客户端的关闭而失效。
5.在 test 库下创建函数,名称为 test.split,在test 库下可直接 split() 方式使用。如需在 default 库下使用,则可通过加 test 前缀使用。

UDF

/**
* 自定义 UDF 函数,需要继承 GenericUDF 类
* 需求: 计算指定字符串的长度
*/
public class MyStringLength extends GenericUDF {
 /**
 *
 * @param arguments 输入参数类型的鉴别器对象
 * @return 返回值类型的鉴别器对象
 * @throws UDFArgumentException
 */
 @Override
 public ObjectInspector initialize(ObjectInspector[] arguments) throws 
UDFArgumentException {

 // 判断输入参数的个数
 if(arguments.length !=1){
 throw new UDFArgumentLengthException("Input Args Length 
Error!!!");
 }
 // 判断输入参数的类型
 
if(!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)
){
 throw new UDFArgumentTypeException(0,"Input Args Type 
Error!!!");
 }
 //函数本身返回值为 int,需要返回 int 类型的鉴别器对象
 return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
 }
 /**
 * 函数的逻辑处理
 * @param arguments 输入的参数
 * @return 返回值
 * @throws HiveException
 */
 @Override
 public Object evaluate(DeferredObject[] arguments) throws 
HiveException {
 if(arguments[0].get() == null){
 return 0;
 }
 return arguments[0].get().toString().length();
 }
 @Override
 public String getDisplayString(String[] children) {
 return "";
 }
}

打成 jar 包上传到服务器/opt/soft/hive312/lib/目录下

在这里插入图片描述

将 jar 包添加到 hive 的 classpath

hive (default)> add jar /opt/soft/hive312/lib/hivestu-2.0.2.jar;

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

hive (default)> create temporary function myudf as "com.nj.hive.MyStringLength";

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

select ename,my_len(ename) ename_len from emp;

UDTF

/*
* UDTF解决输入一行,输出多行的需求
* 输入 "hello,world,liwei,bangbangtang",","
*
* */
public class MyUDTF extends GenericUDTF {
    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        //输出数据类型说明
        ArrayList<String> fieldNames = new ArrayList<>();
        fieldNames.add("word");

        List<ObjectInspector> fieldOIs =new ArrayList<>();
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames,fieldOIs);
    }

    private List<String> wordList =new ArrayList<>();

    @Override
    public void process(Object[] args) throws HiveException {
            //输入 “hello,world,liwei,bangbangtang”
            String data=args[0].toString();
            String splitkey = args[1].toString();

            String[] words = data.split(splitkey);

            for (String word:
                    words) {
                wordList.clear();
                wordList.add(word);
                forward(wordList);
            }
        }
    @Override
    public void close() throws HiveException {
    }
}

后续步骤同上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值