1.什么是UDF?
在Hive中,用户可以自定义一些函数,用于扩展HiveQL的功能,这就是类函数UDF(用户自定义函数)。
hive的类SQL预发给数据挖掘工作者带来了很多便利,海量数据通过简单的sql就可以完成分析,有时候hive提供的函数功能满足不了业务需要,就需要我们自己来写UDF函数来辅助完成,
用户构建的UDF使用过程如下:
第一步:继承UDF或者UDAF或者UDTF,实现特定的方法。
第二步:将写好的类打包为jar。如hivefirst.jar.
第三步:进入到Hive外壳环境中,利用add jar /home/hadoop/hivefirst.jar.注册该jar文件
第四步:为该类起一个别名,create temporary function f1 as ‘com.whut.StringLength’;这里注意UDF只是为这个Hive会话临时定义的。
第五步:在select中使用f1(); 像这样:select f1(字段名) from [tablename];
下面用一个简单的例子说明过程:
2.一个栗子
现在假设我们有一串电话号码,我们想要获取他们的归属地,然后我们罗列一张电话头信息表,元数据+筛选表+UDF函数=地理位置。如下图所示:
这里有一张从kafka(信息队列)那里采集过来的电话号码:
2.1 创建UDF项目 (磨刀):
构建一个maven project,添加下面的依赖:
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.3.3</version>
</dependency>
然后创建一个类,实现查询地址的方法
public class PhoneArea extends UDF {
//重写方法evaluate()
public String evaluate(String phone) throws Exception{
try {
//连接数据库
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://192.168.49.125:3306/phone_area","root","123456");
PreparedStatement ps = con.prepareStatement("select mobileArea from phone_area where mobileNumber=?");
//将hive中的phnum的前7位作为查询条件查询数据
ps.setString(1, phone.substring(0,7));
ResultSet rs = ps.executeQuery();
while(rs.next()){
//根据查询结果进一步筛选地址并返回
return rs.getString("mobileArea");
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return "未知区域";
}
}
2.2 打包(开始料理):
将这个project打成jar包:
然后将你的jar包丢进你的远程服务器里:
2.3 注册该jar文件
再进入你服务器里的开启hive功能(开启hadoop、hive)使用指令 : add jar /当前路径/phone.jar:
2.4 创建临时函数
接着创建一个临时函数:
create temporary function f1 as “包名.类名”;
2.5 查询函数
假设现在你的服务器有一条生肉(元数据),然后先导入你的表你里,那么哪来的表呢?当然是创建一个啦,下面使用无中生有技能:
create table phone(phnum string,area string) row format delimited fields terminated by “,”;
这里,我们格根据需要,创建一张带有phnum和area字段的表,后面表示插入的数据用,分割。
然后,找到生肉的路径,将他切好(hive)
load data local inpath /logs/phone.txt into [tablename];
最后,根据add进来的jar包里的函数,查询想要的结果(烹饪端盘):
select phnum,f1(phnum) from [tablename];