一、Hive自定义函数
Hive 自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展。
当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。
根据用户自定义函数类别分为以下三种:
1、UDF(User-Defined-Function)
一进一出
(例如,通过身份证查询出行政区划)
2、UDAF(User-Defined Aggregation Function)
聚集函数,多进一出
类似于:count/max/min
3、UDTF(User-Defined Table-Generating Functions)
一进多出
如lateral view explore()
1.1 自定义UDF
编程步骤:
(1)继承org.apache.hadoop.hive.ql.UDF
(2)需要实现evaluate函数;evaluate函数支持重载;
注意事项:
(1)UDF必须要有返回类型,可以返回null,但是返回类型不能为void;
(2)UDF中常用Text/LongWritable等类型,不推荐使用java类型;
第一步:创建maven java 工程,导入jar包
# pom配置文件
<repositories>
<repository>
<id>spring</id>
<url>https://repo.spring.io/plugins-release/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
第二步:开发java类继承UDF,并重载evaluate方法
public class MyUDF extends UDF {
public Text evaluate(final Text s){
//1.获取数据
String str = s.toString();
if(str == null){
return null;
}
String upperStr = str.toUpperCase();
return new Text(upperStr);
}
}
第三步:将我们的项目打包,并上传到hive的lib目录下
第四步:添加我们的jar包
重命名我们的jar包名称
cd /export/server/hive-2.1.0/lib
mv original-day_10_hive_udf-1.0-SNAPSHOT.jar my_upper.jar
hive的客户端(命令行)添加我们的jar包
add jar /export/server/hive-2.1.0/lib/my_upper.jar;
第五步:设置函数与我们的自定义函数关联
create temporary function my_upper as 'cn.itcast.udf.MyUDF';
第六步:使用自定义函数
select my_upper('abc');
1.2 自定义UDTF
-
实现一个 udtf 函数 开发步骤
-
需求
源数据:"zookeeper,hadoop,hdfs,hive,MapReduce"目标数据:zookeeperhadoophdfshiveMapReduce
-
创建一个类,这个类继承 GenericUDTF 类
-
重写一个 process 方法
-
将对象数组通过 forword 写出去
-
将 jar 包上传到 hive 环境中 ,add jar
-
add jar /export/server/hive-2.1.0/lib/myudtf.jar
-
-
创建一个临时函数依赖 jar 包 create temporary function fun_name as '全路径类名'
-
create temporary function my_udtf as 'cn.itcast.udf.MyUDF';
-
-
测试 jar 包是否安装成功 list jars
-
-
测试数据准确性
-
select my_udtf("zookeeper,hadoop,hdfs,hive,MapReduce",",");
具体核心代码:
# 创建 udtf 函数
/**
* Author itcast
* Date 2020/8/30 10:19
* Desc TODO
*/
public class MyUDTF extends GenericUDTF {
private final transient Object[] forwardListObj = new Object[1];
//初始化的方法,主要是用来规定 函数的输入输出是个什么类型
@Override
public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
//设置列名的类型
List<String> fieldNames = new ArrayList<>();
//设置列名
fieldNames.add("column_01");
List<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>() ;//检查器列表
//设置输出的列的值类型
fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
}
@Override
public void process(Object[] objects) throws HiveException {
//获取原始数据
String orignal = objects[0].toString();
//获取分割的字符
String splitKey = objects[1].toString();
//将原始数据按照输入的分隔符进行切分
String[] splits = orignal.split(splitKey);
//将对象写出去
for(String s:splits){
//将每个单词添加到值对象数组中
forwardListObj[0]=s;
//将对象数组内容写出去
forward(forwardListObj);
}
}
@Override
public void close() throws HiveException {
}
}