hive--udf函数(开发-4种加载方式)

h2 { color: #fff; background-color: #7CCD7C; padding: 3px; margin: 10px 0px }
h3 { color: #fff; background-color: #008eb7; padding: 3px; margin: 10px 0px }

UDF函数开发

标准函数(UDF):以一行数据中的一列或者多列数据作为参数然后返回解雇欧式一个值的函数,同样也可以返回一个复杂的对象,例如array,map,struct。

聚合函数(UDAF):接受从零行到多行的零个到多个列,然后返回单一值。例如sum函数。

生成函数(UDTF):接受零个或者多个输入,然后产生多列或者多行输出。

udf函数开发

当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数,用户自定义函数(user defined function),针对单条记录。编写一个UDF,需要继承UDF类,并实现evaluate()函数。在查询执行过程中,查询中对应的每个应用到这个函数的地方都会对这个类进行实例化。对于每行输入都会调用到evaluate()函数。而evaluate()函数处理的值会返回给Hive。同时用户是可以重载evaluate方法的。Hive会像Java的方法重载一样,自动选择匹配的方法。

准备数据:

littlebigdata.txt

edward capriolo,edward@media6degrees.com,2-12-1981,209.191.139.200,M,10
bob,bob@test.net,10-10-2004,10.10.10.1,M,50
sara connor,sara@sky.net,4-5-1974,64.64.5.1,F,2

创建表:

create table if not exists littlebigdata(
name string,
email string,
bday string,
ip string,
gender string,
anum int
)
row format delimited fields terminated by ‘,‘;

加载数据:

load data local inpath ‘littlebigdata.txt‘ into table littlebigdata;

代码示例:

import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.junit.Test;

public class UDFZodiacSign extends UDF {

    private  SimpleDateFormat df ;

    public UDFZodiacSign() {
        df = new SimpleDateFormat("MM-dd-yyyy");
    }

    public  String evaluate(Date bday){
        return evaluate(bday.getMonth(),bday.getDay());
    }

    public  String evaluate(String bday){
        Date date =null;
        try{
            date = df.parse(bday);
        }
        catch(Exception ex){
            System.out.println("异常");
            ex.printStackTrace();
            return null;
        }
        return evaluate(date.getMonth()+1,date.getDay());
    }

    public  String evaluate(Integer month,Integer day){
        if(month ==1){
            if(day<20){
                return "Capricorn";
            }else{
                return "Aquarius";
            }
        }
        if(month ==2){
            if(day<19){
                return "Capricorn";
            }else{
                return "Pisces";
            }
        }
        if(month ==3){
            if(day<20){
                return "Pisces";
            }else{
                return "Aries";
            }
        }
        if(month ==4){
            if(day<20){
                return "Aries";
            }else{
                return "Taurus";
            }
        }
        if(month ==5){
            if(day<20){
                return "Taurus";
            }else{
                return "Gemini";
            }
        }
        if(month ==6){
            if(day<21){
                return "Gemini";
            }else{
                return "Cancer";
            }
        }
        if(month ==7){
            if(day<22){
                return "Cancer";
            }else{
                return "Leo";
            }
        }
        if(month ==8){
            if(day<23){
                return "Leo";
            }else{
                return "Virgo";
            }
        }
        if(month ==9){
            if(day<22){
                return "Virgo";
            }else{
                return "Libra";
            }
        }
        if(month ==10){
            if(day<24){
                return "Libra";
            }else{
                return "Scorpio";
            }
        }
        if(month ==11){
            if(day<22){
                return "Scorpio";
            }else{
                return "Sagittarius";
            }
        }
        if(month ==12){
            if(day<22){
                return "Sagittarius";
            }else{
                return "Capricorn";
            }
        }

        return null;
    }
    @Test
    public void test() {

        UDFZodiacSign aa = new UDFZodiacSign();
        String str = aa.evaluate("01-10-2004");
        System.out.println(str);
    }

}

udf代码示例

函数使用

加载:

add jar testUDF-0.0.1-SNAPSHOT.jar;
create temporary function zodiac as "cn.rtmap.bigdata.hive.testUDF.udf.UDFZodiacSign";

查询:

select name,bday,zodiac(bday) from littlebigdata;

结果:

edward capriolo    2-12-1981    Capricorn
bob    10-10-2004    Libra
sara connor    4-5-1974    Aries

注意:这个地方可能有报错,反正我是遇到了!

解决办法:

1,修改jdk的版本 可能版本太高。

2,删除META-INF 文件中*.SF的文件,这个是依赖包有冲突导致的。

3.在MANIFEST.MF 中添加Main-Class: cn.rtmap.bigdata.hive.testUDF.udf.UDFZodiacSign,这个可以在maven中创建好。

UDF四种加载方式

第一种:

是最常见但也不招人喜欢的方式是使用ADD JAR(s)语句,之所以说是不招人喜欢是,通过该方式添加的jar文件只存在于当前会话中,当会话关闭后不能够继续使用该jar文件,最常见的问题是创建了永久函数到metastore中,再次使用该函数时却提示ClassNotFoundException。所以使用该方式每次都要使用ADD JAR(s)语句添加相关的jar文件到Classpath中。

第二种:

是修改hive-site.xml文件。修改参数hive.aux.jars.path的值指向UDF文件所在的路径。,该参数需要手动添加到hive-site.xml文件中。

<property>
<name>hive.aux.jars.path</name>
<value>file:///jarpath/all_new1.jar,file:///jarpath/all_new2.jar</value>
</property>

 第三种:

是在${HIVE_HOME}下创建auxlib目录,将UDF文件放到该目录中,这样hive在启动时会将其中的jar文件加载到classpath中。(推荐)

 第四种:

是设置HIVE_AUX_JARS_PATH环境变量,变量的值为放置jar文件的目录,可以拷贝${HIVE_HOME}/conf中的hive-env.sh.template为hive-env.sh文件,并修改最后一行的#export HIVE_AUX_JARS_PATH=为exportHIVE_AUX_JARS_PATH=jar文件目录来实现,或者在系统中直接添加HIVE_AUX_JARS_PATH环境变量。

时间: 2024-10-01 22:36:33

hive--udf函数(开发-4种加载方式)的相关文章

Linux驱动的两种加载方式过程分析

一.概念简述 在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载. 静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用.静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新编译和下载内核,效率较低.若采用静态加载的驱动较多,会导致内核容量很大,浪费存储空间. 动态加载利用了Linux的module特性,可以在系统启动后用insmod命令添加模块(.ko),在不需要的时候用rmmod命令卸载模块,采用这种动态加载的方式便于驱动程序的调试,同时可以针对产品的功能需求,进行

三种加载方式

重点总结:    即:三种加载方式    1>传统加载方式------默认路径:tomcat/bin/目录    2>使用ServletContext对象-----默认路径:web应用(工程)目录    3>使用类加载器------默认路径:WEB-INF/classes/目录 一.利用ServletContext对象读取资源文件--默认目录为:工程(应用)路径                重点方法:                        InputStream getReso

UIImage的两种加载方式

UIImage的两种加载方式 1.有缓存:读取后放入缓存中下次可直接读取,适用于图片较少且频繁使用. [UIImage imageNamed:@"文件名"]: 在缓存中由系统管理,当收到memoryWarning时会释放这些内存资源. 2.无缓存:用完就释放掉,参数传的是全路径,适用于图片较多较大的情况下. NSString *path = [[NSBundlemainBundle] pathForResource: @"1.png"ofType: nil]; [U

(备忘)vs2010编写动态链接库时导出函数的函数名问题及加载方式

在vs2010中使用.def文件导出函数时,仅仅添加.def文件是不够的,还要在 项目属性 -> 链接器 -> 输入 -> 模块定义文件 中添加自定义的.def文件名. (前提:导入导出都在头文件和源文件中定义好了) ##:静态加载动态链接库 将链接库的 头文件..lib文件 和 .dll 文件拷贝到工程目录下 然后#include 头文件,#pragma comment(lib,"**.lib") 最后直接在需要使用dll函数的地方使用函数就行 ##:动态加载动态链

dll的两种加载方式(pend)+ delayload

看过关于动态库的调用例子,于是决定动手做一做:dll的对外接口声明头文件,Mydll.h: //Mydll.h #include <stdio.h> #include <stdlib.h> #include "Public.h" #define DLL_EXPORT /*extern "c"*/ __declspec(dllexport) //导出 #define CUST_API _stdcall //标准调用 DLL_EXPORT voi

Linux共享库两种加载方式简述

动态库技术通常能减少程序的大小,节省空间,提高效率,具有很高的灵活性,对于升级软件版本也更加容易.与静态库不同,动态库里面的函数不是执行程序本身 的一部分,而是在程序执行时按需载入,其执行代码可以同时在多个程序中共享.由于在编译过程中无法知道动态库函数的地址,所以需要在运行期间查找,这对程 序的性能会有影响. 共享库 对于共享库来讲,它只包括2个段:只读的代码段 和可修改的数据段.堆和栈段,只有进程才有.如果你在共享库的函数里,分配了一块内存,这段内存将被算在调用该函数的进程的堆中.代码段由于其

ios 图片的两种加载方式

控件加载图片,plist,懒加载,序列帧动画,添加动画效果. IOS中有2种加载图片的方式. 方式一:有缓存(图片所占用的内存会一直停留在程序中) [objc] view plaincopy + (UIImage *)imageNamed:(NSString *)name; 注:必须是png文件.需要把图片添加到 images.xcassets中 例如: [objc] view plaincopy @property (weak, nonatomic) IBOutlet UIImageView 

【Android进阶篇】Fragment的两种加载方式

一.概述 Fragment(碎片,片段)是在Android 3.0后才引入的,主要的目的是为了实现在大屏幕设备上的更加动态更加灵活的UI设计.这是因为平板电脑的屏幕比手机大得多,所以屏幕上可以放更多的组件,而不是简单地只是把手机上的组件放大.所以Fragment在应用中的是一个可重用的模块化组件,它有自己的布局.自己的生命周期,在一个Activity中可以包含多个Fragment. 二.在Activity中加载Fragment Fragment的加载方式包含两种:静态加载和动态加载.静态加载很简

MyBatis 延迟加载的三种加载方式深入,你get了吗?

延迟加载 延迟加载对主对象都是直接加载,只有对关联对象是延迟加载. 延迟加载可以减轻数据库的压力, 延迟加载不可是一条SQL查询多表信息,这样构不成延迟加载,会形成直接加载. 延迟加载分为三种类型: 1.直接加载 执行完主对象之后,直接执行关联对象. 2.侵入式加载 在执行主对象详情的时候,执行关联对象. 3.深度延迟加载 执行完主对象或主对象详情不会执行关联对象,只有用到关联对象数据的时候才走深度延迟加载. 延迟加载默认情况下是关闭状态(false) 延迟加载下的侵入式加载默认情况下是开启状态