大数据基础之HIVE(四)——简单自定义UDF、UDTF、UDAF函数

概述:

 UDF函数其实就是一个简单的函数,执行过程就是在Hive转换成MapReduce程序后,执行java方法,类似于像MapReduce执行过程中加入一个插件,方便扩展。UDF只能实现一进一出的操作,如果需要实现多进一出,则需要实现UDAF。
 Hive可以允许用户编写自己定义的函数UDF,来在查询中使用。

UDF类型:

Hive中有三种UDF:
UDF:操作单个数据行,产生单个数据行;
UDAF:操作多个数据行,产生一个数据行;
UDTF:操作一个数据行,产生多个数据行一个表作为输出;

如何构建UDF(原理):

用户构建UDF使用过程如下:

  1. 继承UDF或者UDAF或者UDTF,实现特定的方法;
  2. 将写好的类打包成jar包,将jar包上传到Linux中;
  3. 在Linux中将jar上传到Hadoop中的hdfs上;
  4. 然后在hive黑窗口界面中输入以下命令:create function myfunc(自定义方法名) as “com.kb06.UdfFunction”(类的全包路径) using jar “hdfs://192.168.56.101:9000/func/myfun.jar”(jar包在hdfs上的位置);
  5. 最后在select中调用该函数就可以了, select myfunc();

UDF代码实现:

pom.xml依赖

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <version>2.6.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
    <dependency>
      <groupId>org.apache.hive</groupId>
      <artifactId>hive-exec</artifactId>
      <version>1.1.0</version>
    </dependency>
  </dependencies>

如果想改打包之后的包名,可以在pom文件中的build标签内加一个标签,操作如下图:
在这里插入图片描述
UDF代码:
我的业务是想统计集合里面male和female的个数

package com.kb06;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

import java.util.ArrayList;

public class MyFunc extends UDF {
    public Text evaluate(ArrayList<Text> txt){
        int male = 0;
        int female = 0;
        for (Text text : txt) {
            String sex = text.toString();
            if(sex.equalsIgnoreCase("male")){
                male++;
            }else {
                female++;
            }
        }
        return new Text("male"+male+",female"+female);
    }
}

打成jar包:
在这里插入图片描述
注册UDF:

//先将jar包上传到Linux,然后上传到hdfs上
hdfs dfs -put /opt/myfun.jar /func
//注册UDF
create function myfunc as "com.kb06.UdfFunc" using jar "hdfs://192.168.56.101:9000"/func/myfun.jar

测试:

select myfunc(collect_list(gender)) from students;

UDTF代码实现:

 编写UDTF需要继承GenericUDTF类,然后重写initialize方法和process方法和close方法

 initialize方法主要是初始化返回的列和返回的列类型

 process方法对输入的每一行进行操作,他通过调用forward()返回一行或者多行数据

 close方法在process方法结束后调用,用于进行一些其他的操作,只执行一次

通过UDTF将爱好拆分为两列

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import java.util.ArrayList;

public class SimpleUDTF extends GenericUDTF {

    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        ArrayList<String> colNames = new ArrayList<String>();
        colNames.add("hobby1");
        colNames.add("hobby2");
        ArrayList<ObjectInspector> fieldIOs = new ArrayList<ObjectInspector>();
        fieldIOs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        fieldIOs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        return ObjectInspectorFactory.getStandardStructObjectInspector(colNames,fieldIOs);
    }

    public void process(Object[] objects) throws HiveException {
        forward(objects[0].toString().split(","));
    }

    public void close() throws HiveException {

    }
}

打包测试:

add jar test_udtf.jar
create temporary function udf as 'com.mwf.demo.SimpleUDTF'
select udtf(hobby) from user;

UDAF代码实现:

可以参考该网址:UDAF精讲

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值