上节课我们一起学习了Hive进行多表联合查询,这节课我们一起来学习一下Hive的自定义UDF。
第一步:创建Hive工程
我们这里为了简单就不用Maven了,而是直接使用lib包并把我们需要的jar包放到lib当中。如下所示。
我们需要把hive的lib下的所有的包放到lib下,hive的jar包所在的位置如下图所示。
光导hive的包还不行,我们还需要用到hadoop-common-2.2.0.jar,这个包的位置如下图所示。
我们把jar拷到hive-udf工程下的lib包后记得选中所有的jar包,然后右键在菜单中把鼠标放到"Build path"上,这时会出现子菜单,然后点击"Add to Build path"添加到工程当中。
第二步:写UDF代码
我们新建了一个NationUDF类,该类所在的包是cn.itcast.hive.udf,代码如下所示。
import java.util.Map;
import org.apache.hadoop.io.Text;
//我们要实现的业务逻辑非常简单,就是传过来一个英文的国家名,然后返回一个中文,它们的映射关系肯定事先就定义好了,
//不可能等到调用的时候了才建立映射关系。
public static Map<String,String> nationMap=new HashMap<String,String>();
static{
nationMap.put("China", "中国");
nationMap.put("Japan", "小日本");
nationMap.put("USA", "美帝");
}
Text text=new Text();
//重写UDF,就是要写evaluate方法,注意方法名一定得是这个。这个方法是非常灵活的,参数可以有多个,返回值如果想要多个的话,可以封装成一个对象。
public Text evaluate(Text nation){
//先得到传过来的英文的国家名
String nation_e=nation.toString();
//根据英文名得到中文名
String nation_cn=nationMap.get(nation_e);
if(nation_cn==null){
//如果得到的值是null,说明没有对应的映射关系,我们就输出火星人
text.set("火星人");
return text;
}
text.set(nation_cn);
return text;
}
}
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.reduce.tasks is deprecated. Instead, use mapreduce.job.reduces
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.min.split.size is deprecated. Instead, use mapreduce.input.fileinputformat.split.minsize
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.reduce.tasks.speculative.execution is deprecated. Instead, use mapreduce.reduce.speculative
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.min.split.size.per.node is deprecated. Instead, use mapreduce.input.fileinputformat.split.minsize.per.node
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.input.dir.recursive is deprecated. Instead, use mapreduce.input.fileinputformat.input.dir.recursive
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.min.split.size.per.rack is deprecated. Instead, use mapreduce.input.fileinputformat.split.minsize.per.rack
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.max.split.size is deprecated. Instead, use mapreduce.input.fileinputformat.split.maxsize
16/11/07 00:49:58 INFO Configuration.deprecation: mapred.committer.job.setup.cleanup.needed is deprecated. Instead, use mapreduce.job.committer.setup.cleanup.needed
hive> add jar /root/NationUDF.jar;
Added /root/NationUDF.jar to class path
Added resource: /root/NationUDF.jar
hive> create temporary function getNation as 'cn.itcast.hive.udf.NationUDF';
OK
Time taken: 0.264 seconds
OK
1 赵薇 30 China
2 赵丽颖 29 China
3 赵雅芝 62 China
1 福原爱 30 Japan
2 井上航平 22 Japan
3 酒井法子 45 Japan
hive>
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Starting Job = job_1478527660121_0001, Tracking URL = http://itcast03:8088/proxy/application_1478527660121_0001/
Kill Command = /itcast/hadoop-2.2.0/bin/hadoop job -kill job_1478527660121_0001
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0
2016-11-07 22:17:49,928 Stage-1 map = 0%, reduce = 0%
2016-11-07 22:17:59,324 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 1.28 sec
MapReduce Total cumulative CPU time: 1 seconds 280 msec
Ended Job = job_1478527660121_0001
MapReduce Jobs Launched:
Job 0: Map: 1 Cumulative CPU: 1.28 sec HDFS Read: 332 HDFS Write: 144 SUCCESS
Total MapReduce CPU Time Spent: 1 seconds 280 msec
OK
1 赵薇 30 中国
2 赵丽颖 29 中国
3 赵雅芝 62 中国
1 福原爱 30 小日本
2 井上航平 22 小日本
3 酒井法子 45 小日本
Time taken: 26.942 seconds, Fetched: 6 row(s)
hive>