hive实现自定义函数

本文介绍了在Hive中实现自定义函数的过程,包括UDF(一进一出)、UDTF(多进多出)及其升级版,强调了通过源码阅读理解函数工作原理的重要性。同时,讲解了如何创建临时和永久函数,以及在遇到过时类时的解决办法。
摘要由CSDN通过智能技术生成

0.编程思想得到升华

  1. 当写这个框架的自定义类时,大都要继承框架的某些类
  2. 框架中的对象基本都是再次包装过的,基本不能之间 new 出来 ,可以考虑在对象名后面加上factory(工厂)
  3. 当学习新的知识时,看源码是一个非常好的方式,虽然现在还是看得有点懵逼,不过可以先理解大致流程.
  4. 实现类时,编写简单或自己用的函数,自需要写官方规定的方法即可。一般都是抽象方法会有提示.

0. hive中用到的对象

  1. Cloneable: 可克隆的 是一个接口
  2. ObjectInspector: obj对象鉴别器 是一个接口 继承与 Cloneable
  3. ObjectInspectorFactory: obj对象鉴别器工厂 是一个final class 最终类 用于生产对象
  4. PrimitiveObjectInspectorFactory: 基本类型 obj对象鉴别器工厂 是一个final class 最终类 与 java类型对接
  5. StructObjectInspector : 结构体obj对象鉴别器 是一个实现类 实现了 ObjectInspector 接口 是一个抽象类 干啥的没解析注释看不懂!!!

1.UDF

一进一出

package review.myudf;


import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
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.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

/**
 *  一般写框架的函数里面的数据类型对象 都是经过包装的 而且一般都不能 new 出来
 * 实现自定义 udf
 * 功能: 输入 一个基本数据类型 数据
 *      输出  长度
 *
 * 此次编写函数  参考了 官方的 GenericUDFAbs类
 */

public class GetLengthStr extends GenericUDF {
   
    /**
     * 初始化方法
     * @param arguments  obj鉴别器对象数组(hive包装的)
     * @return
     * @throws UDFArgumentException
     */
    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
   
        // 1.判断参数个数
        if (arguments.length != 1 || arguments == null){
   
            // 抛出异常
            throw new UDFArgumentLengthException("参数数量只能是一个");
        }
        // 2.判断参数类型 要求基本数据类型
        if (arguments[0].getCategory() != ObjectInspector.Category.PRIMITIVE){
   
            throw new UDFArgumentTypeException(0, "参数类型异常");
        }
        // 3.返回该对象数据类型
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
    }

    /**
     * 核心业务处理逻辑
     * @param arguments 这是函数传进来的参数
     * @return
     * @throws HiveException
     */
    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
   
        // 1.先获取参数
        Object str = arguments[0].get();
        // 2.考虑null值的特殊型 因为 hive中 有null   不是这个"null" 这是字符串
        if (str == null){
   
            return 0;
        }
        // 3.获取长度
        int length = str.toString().length();
        // 4.返回结果
        return length;
    }

    @Override
    public String getDisplayString(String[] children) {
   
        return "";
    }
}

对比源码:

public class GenericUDFAbs extends GenericUDF {
   
  private transient PrimitiveCategory inputType;
  private final DoubleWritable resultDouble = new DoubleWritable();
  private final LongWritable resultLong = new LongWritable();
  private final IntWritable resultInt = new IntWritable();
  private final HiveDecimalWritable resultDecimal = new HiveDecimalWritable();
  private transient PrimitiveObjectInspector argumentOI;
  private transient Converter inputConverter;

  @Override
  public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
   
    if (arguments.length != 1) {
   
      throw new UDFArgumentLengthException(
          "ABS() requires 1 argument, got " + arguments.length);
    }

    if (arguments[0].getCategory() != Category.PRIMITIVE) {
   
      throw new UDFArgumentException(
          "ABS only takes primitive types, got " + arguments[0].getTypeName());
    }
    argumentOI = (PrimitiveObjectInspector) arguments[0];

    inputType = argumentOI.getPrimitiveCategory();
    ObjectInspector outputOI = null;
    switch (inputType) {
   
    case SHORT:
    case BYTE:
    case INT:
      inputConverter = ObjectInspectorConverters.getConverter(arguments[0],
          PrimitiveObjectInspectorFactory.writableIntObjectInspector);
      outputOI = PrimitiveObjectInspectorFactory.writableIntObjectInspector;
      break;
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值