hive UDF函数

1.一直在公司琢磨hive的UDF和UDAF函数,几番测试还是不通。

业务场景:物流企业有路由和线路,每条线路有班次,报表需求要求传入路由参数后,返回在最后一站的达到时刻?



此业务场景sql通过临时表觉得不是高手搞不定,想到hive的UDF函数。

问题:1.理由有几条线路组成?  未知数,离不开循环和递归了

            2.每条线路有多班次,选择哪个班次? 在循环里套出班次的循环并判断

            3.一条路由肯定返回一个时刻


UDF函数java代码如下,有点长没怎么优化:

package com.hive;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;


import org.apache.hadoop.hive.ql.exec.UDF;


public class Route extends UDF {
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static String line_time = null;
    public static String split_code = "-";
    public static Map map = new HashMap<String, String>();
    public static Statement stmt= null;
    
public static void main(String[] args) {
String driver = "org.apache.hive.jdbc.HiveDriver";
String url = "jdbc:hive2://192.168.175.129:10000";
String name = "";
String pwd = "";
// SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String route_line = "select line_id,route_code from galaxyods.route_line";
String route_code = "123W-345W-456W";
String consiter_time = "2017-05-02 13:00:00";
try {
Class.forName(driver);
Connection con = DriverManager.getConnection(url, name, pwd);
stmt = con.createStatement();
ResultSet res = stmt.executeQuery(route_line);
setRouteLine(map,res);
String last_time = get_route_time(route_code,consiter_time);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



}





private static String get_route_time(String route_code, String consiter_time) {
// TODO Auto-generated method stub
try {

if (route_code.split(split_code).length != 0 && map.size() > 0) {


for (int i = 0; i < route_code.split(split_code).length - 1; i++) {
// 取到匹配code时候的line_id值
if (map.get(route_code.split(split_code)[i] + split_code
+ route_code.split(split_code)[i + 1]) != null) {
ResultSet route_line_shifts = stmt
.executeQuery(
"select t.start_time,t.end_time,t.last_arrive_time from galaxyods.route_line_shifts t where t.line_id = "
+ map.get(route_code.split(split_code)[i] + split_code
+ route_code.split(split_code)[i + 1])
+ " order by t.start_time");
// 传入寄件时间和班次集合,返回一个到达时间
line_time = get_line_time(consiter_time, route_line_shifts);
// 把达到时间赋给寄件时间变量,继续查找第二条线路...
if (line_time != null) {
consiter_time = line_time;
} else {
System.out.println("获取到达时间异常");
}
}
// 如果没有找到或者一次都没有找到匹配的线路都应该返回失败消息,表示此企业不可以抵达
else {
System.out.println("此路由无法找到规定到达时间");
}
}
System.out.println("线路抵达时间是:" + line_time);
}


} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return consiter_time;
}
 






/*
* 对获得的线路填充到map集合中便于每次遍历取出line_id*/
private static void setRouteLine(Map map, ResultSet res) {
// TODO Auto-generated method stub
try {
while (res.next()) {
map.put(res.getString(2), res.getInt(1) + "");
System.out.println(map.get(res.getString(2)));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}




/*
* 对寄件时间和班次判断取出到达时间*/
public static String get_line_time(String consiter_time, ResultSet route_line_shifts) {
// TODO Auto-generated method stub
String arrive_time = null;
try {
String set_time = consiter_time.substring(0, 10) + " ";
while (route_line_shifts.next()) {
if (sdf.parse(consiter_time).getTime() <= sdf.parse(set_time + route_line_shifts.getString(3)).getTime()
&& sdf.parse(set_time + route_line_shifts.getString(1)).getTime() <= sdf.parse(set_time + route_line_shifts.getString(2)).getTime()) {
return set_time + route_line_shifts.getString(2);
} else if (sdf.parse(consiter_time).getTime() <= sdf.parse(set_time + route_line_shifts.getString(3))
.getTime()
&& sdf.parse(set_time + route_line_shifts.getString(1)).getTime() > sdf.parse(set_time + route_line_shifts.getString(2)).getTime()) {

return getAddDate(set_time + route_line_shifts.getString(2),1);
}
}
if (arrive_time == null) {
return getAddDate(set_time + route_line_shifts.getString(2),1);

}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;


}

/*
* 对获得的日期加1天日期计算*/
public static String getAddDate(String current_time,int days)
{
Date date = new Date();
Calendar calendar = new GregorianCalendar();
//route_line_shifts.beforeFirst();
try {
date = sdf.parse(current_time);

calendar.setTime(date);
calendar.add(Calendar.DATE, days);
return sdf.format(calendar.getTime());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sdf.format(calendar.getTime());

}


}


添加jar包

hive --auxpath /usr/hive/myjar/


创建函数名

create temporary function maxvalue as "com.hive.udaf.Maximum";




PS:以上代码是测试代码,没有写成evaluate这个函数名


运行报错问题:没有捕捉截图,总结以下问题,jdk版本一定要和环境一致,这个是重点,其他的都是逻辑和执行命令问题。

                            

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值