牛骨文教育服务平台(让学习变的简单)
博文笔记

使用hiveF对sql语句的封装

创建时间:2015-10-19 投稿人: 浏览次数:1421

关于使用hiveF对sql语句的封装,平时我们使用 hive –e “$sql” 进行操作,由于sql语句会很长,造成shell脚本很长阅读不便,且不利用于维护。

现在提供hiveF 对sql 进行封装,具体使用如下:


1、解析sql文件中的参数,并转换成map对象。

package com.hexun.hiveF;

import java.util.HashMap;
import java.util.Map;

/**
 * 解析sql文件中的参数,并转换成map对象。
 * @author Administrator
 *
 */
public class ParseArgs {
	private Map<String, String> map = null;

	public ParseArgs(String[] args) {
		map = new HashMap<String, String>();

		if (args.length == 0) {
			return;
		}
		int i = 0;
		while (i < args.length) {
			String par = args[i].trim();
			if (par.startsWith("-")) {
				String key = par.substring(1).trim();
				i++;
				String value = null;
				if (args.length > i) {
					value = args[i].trim();
					if (value.startsWith(""") || value.startsWith(""")) {
						value = value.substring(1, value.length() - 1).trim();
					}
				}
				map.put(key, value);
				i++;
			} else {
				i++;
			}

		}

	}

	public Map<String, String> getMap() {
		return map;
	}

}

2、解析sql文件中的SQL语句,并返回解析后的语句

package com.hexun.hiveF;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Map;

/**
 * 解析sql文件中的SQL语句,并返回解析后的语句
 * @author Administrator
 *
 */
public class Utils {
	public static final String BEGIN = "${";
	public static final String END = "}";

	public static String getSql(File file) throws Exception {
		BufferedReader bf = new BufferedReader(new FileReader(file));
		StringBuffer sqlBuffer = new StringBuffer();
		String temp = null;
		while ((temp = bf.readLine()) != null) {
			String tmp = temp.trim();
			if (tmp.length() == 0 || tmp.startsWith("#") || tmp.startsWith("--")) {
				continue;
			}
			sqlBuffer.append(tmp + " ");
		}
		bf.close();
		return sqlBuffer.toString();

	}

	/**
	 * 把sql里的参数引用,替换为map里的value
	 * 
	 * @param sql
	 * @param map
	 */
	public static String parse(String sql, Map<String, String> map) {
		int begin = sql.indexOf(BEGIN);
		while (begin != -1) {
			String suffix = sql.substring(begin + BEGIN.length());
			int end = begin + BEGIN.length() + suffix.indexOf(END);
			String key = sql.substring(begin + BEGIN.length(), end).trim();
			if (map != null && map.get(key) != null) {
				sql = sql.substring(0, begin) + map.get(key) + sql.substring(end + 1, sql.length());
			} else {
				throw new RuntimeException("Invalid Expression.....");
			}
			begin = sql.indexOf(BEGIN);
		}
		return sql;
	}
}


3、hiveF的客户端

package com.hexun.hiveF;

import java.io.File;

/**
 * hiveF的客户端
 * 
 * eg : hiveF /opt/bin/jar/test.sql -yesterday 20151015 -today 20151016 -hour 15
 * 
 * 第一个参数为sql文件的全路径,第二、三参数等为sql语句中的参数,且格式为: -key value。
 * 
 * @author Administrator
 *
 */
public class Main {
	public static void main(String[] args) throws Exception {
		if (args == null || args.length == 0) {
			System.out.println("请输入参数,第一个参数为sql文件的全路径,第二、三等为sql语句中的参数: -key value,例如: hiveF /opt/bin/jar/test.sql -yesterday 20151015 -today 20151016 -hour 15 ");
			return;
		}

		ParseArgs parse = new ParseArgs(args);
		String sql = Utils.getSql(new File(args[0]));
		System.out.println(Utils.parse(sql, parse.getMap()));
	}
}


4、调用shell脚本编写

#!/bin/bash
source /etc/profile
sql=`/usr/java/jdk1.7.0_67-cloudera/bin/java -jar /opt/bin/hiveF/jars/hiveF.jar $*`
echo "$sql"

#hive -e "$sql"

if [[ "$sql" =~ ^请输入参数 ]]; then
        exit
else
        hive -e "$sql"
fi



5、测试实例:

test.sql

insert overwrite  table default.kwu_tracklog PARTITION (day="${yesterday}",hour="${hour}") 
select datetime,ip,cookieid,userid, logserverip,referer,
requesturl ,remark1,remark2,alexaflag,ua,wirelessflag from ods.tracklog where  day="${today}"  and length(datetime)=12 limit 25000


sql语句中有三个参数:
yesterday, hour, today
 
hiveF以–key value 来传递参数:
hiveF test.sql -yesterday 20151015-today 20151016 -hour 15


声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。