通过创建中间表来存储查询出的信息
use test;
show tables;
select * from make limit 10;
create table t1 as select * from make limit 10;
select * from t1;
create table t2 as
select floor(p.age/10) as age,sum(o.retail) as sum
from orders o left join purchaser p
on o.puechaserId = p.id
group by floor(p.age/10);
select * from t2;
在HiveJDBC操作Hive的基础上封装工具类
HiveUtil.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class HiveUtil {
private Statement statement = null;
public HiveUtil() {
open();
}
static {
// 1.加载驱动
try {
Class.forName("org.apache.hive.jdbc.HiveDriver");
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
private void open() {
try {
// 2.打开连接
Connection connection = DriverManager.getConnection("jdbc:hive2://SZ01:10010/test");
// 3.获得操作对象
statement = connection.createStatement();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
/**
* 创建数据库 - 用户注册时调用
* @param databaseName 根据用户标识生成的数据库名称
*/
public void createDatabase(String databaseName) {
try {
statement.execute("create database " + databaseName);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
/**
* 切换数据库 - 只对当前会话有效
* @param databaseName 目标数据库名称
*/
public void changeDatabase(String databaseName) {
try {
statement.execute("use " + databaseName);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
/**
* 获得当前数据库中的数据列表 - 注意切换数据库
* @return 数据表名称的集合
*/
public List getTableList() {
List list = new ArrayList<>();
try {
ResultSet rs = statement.executeQuery("show tables");
while(rs.next()) {
list.add(rs.getString(1));
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return list;
}
/**
* 获得数据表的简要信息
* @param tableName 数据表名称
* @return 列名及列的数据类型
*/
public List descTable(String tableName){
List list = new ArrayList<>();
try {
ResultSet rs = statement.executeQuery("desc " + tableName);
while(rs.next()) {
list.add(rs.getString(1) + "\t" + rs.getString(2));
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return list;
}
/**
* 获取数据表前十条的预览数据
* @param tableName 数据表名称
* @return 数据表预览数据
*/
public List tableMsg(String tableName){
int tableSize = descTable(tableName).size();
List list = new ArrayList<>();
try {
ResultSet rs = statement.executeQuery("select * from "+ tableName +" limit 10");
while(rs.next()) {
String a = "";
for(int i = 1; i <= tableSize; i++) {
a += rs.getString(i) + "\t";
}
list.add(a);
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return list;
}
/**
* 获得查询sql执行后的返回结果
* @param sql 用户自定义sql
* @return sql执行结果集中的所有数据
*/
public List getResultData(String sql){
List list = new ArrayList<>();
// 生成一个对于当前流程唯一的中间表名称
// 如果流程会反复执行则先删除该表再创建
String tableName = "data_flow";
sql = "create table " + tableName + " as " + sql;
try {
// 执行查询语句,同时使用一个表进行记录
statement.execute(sql);
// 获得中间表的列信息 - 取决于用户执行sql的结果集结构
int tableSize = descTable(tableName).size();
ResultSet rs = statement.executeQuery("select * from " + tableName);
while(rs.next()) {
String a = "";
for(int i = 1; i <= tableSize; i++) {
a += rs.getString(i) + "\t";
}
list.add(a);
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return list;
}
}
HiveUtilTest.java
import java.util.List;
import com.cry.hive.util.HiveUtil;
public class HiveUtilTest {
public static void main(String[] args) {
int userId = 1;
HiveUtil hiveUtil = new HiveUtil();
// 创建库
hiveUtil.createDatabase("user" + userId);
// 切换库
hiveUtil.changeDatabase("test");
// 获取当前库中的表列表
List tables = hiveUtil.getTableList();
for (String table : tables) {
System.out.println(table);
// 获取表结构信息
List columns = hiveUtil.descTable(table);
for (String string : columns) {
System.out.println(string);
}
// 获取表内数据信息
List tableMsg = hiveUtil.tableMsg(table);
for (String string : tableMsg) {
System.out.println(string);
}
System.out.println();
}
// 执行sql语句并获得返回结果
String sql = "SELECT t.typeName,SUM(o.retail) as sum FROM orders o LEFT JOIN type t ON o.typeId = t.id GROUP BY o.typeId,t.typeName";
List list = hiveUtil.getResultData(sql);
for (String line : list) {
System.out.println(line);
}
}
}
在Hive架构图中,CLI和JDBC都已经使用过,还有一种操作Hive的方式WebGUI,即hwi
hwi依赖hive-hwi-1.2.2.war,但是hive安装包目录的lib目录下没有提供,所以需要下载hive的源码包自行打包。
从apache官网下载apache-hive-1.2.2-src.tar.gz
通过Xftp将源码包上传至CentOS
解压缩
tar -zxvf apache-hive-1.2.2-src.tar.gz
进入解压缩出来的文件夹中hwi/web目录下
cd apache-hive-1.2.2-src/hwi/web
使用命令打包web文件夹
jar cvfM hive-hwi-1.2.2.war -C web .
将打包完成的war文件移动至hive安装目录的lib目录下
mv hive-hwi-1.2.2.war $HIVE_HOME/lib
移动完成后,尝试启动hwi服务,此时启动报错,原因是为在hive-site.xml中没有指定hwi目录
hive –service hwi
此时修改配置文件hive-site.xml,添加以下内容
hive.hwi.war.file
lib/hive-hwi-1.2.2.war
注:apache官网中建议配置三项,其中两项默认即可,一是主机0.0.0.0,二是端口号9999,第三项hive.hwi.war.file需指定
再次尝试启动服务
hive –service hwi
发现依旧此时报错,原因是hive缺少jsp依赖
此时可以访问9999端口,但是报错
缺少的jar包可通过Maven下载,点击进入
搜索jasper,下载Jasper Runtime和Jasper Compiler
还缺少commons-el的jar包,一起下载即可
还缺少tools.jar,此jar包在jdk的lib中
总共需要的jar包如下图
将这四个jar包通过Xftp上传至CentOS的$HIVE_HOME/lib目录下
重启hwi服务,即可正常使用
Ctrl + c
hive –service hwi
hive –service hwi命令需要停在当前窗口会话,如果ctrl+c或者关闭会话,服务则无法使用,此时执行以下命令
nohup hive –service hwi > /dev/null 2>&1 &
此命令的含义是开启后台进程并且丢弃nohup.out文件
在Web中操作Hive,需要给每个用户分配独有的空间,否则容易发生冲突,而且会把数据库内弄得杂乱,不好管理
用户注册,相当于在HDFS创建相应的目录(MapReduce),在Hive中新建相应的库
数据库的切换有两种方式:
(1)打开连接时指定数据库
(2)使用前切换至相应的数据库下
数据流管理:数据源在经过多次处理后才能得出最终结果,所以在数据库中需专门建立数据库存放在操作过程中生成的中间表,避免数据库中杂乱无章
目标功能:在页面中显示一个按钮,点击后展示数据库中的所有表
datasource.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
<script type="text/javascript" src="js/jquery-1.7.1.min.js">script>
<script type="text/javascript" src="js/datasource.js">script>
head>
<body>
<input class="showTables" type="button" value="显示数据表" />
<div class="tableList">div>
<div class="tableInfo">div>
<div class="tableData">div>
body>
html>
datasource.js
$(function() {
$(".showTables").click(function() {
var databaseName = "test";
$.ajax({
url : "DataSourceServlet",
type : "post",
data : {
databaseName : databaseName
},
dataType : "json",
success : function(data) {
var content = $(".tableList");
for (index in data) {
var tableName = data[index];
content.append(""+ tableName +"");
}
}
})
})
})
DataSourceServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sand.util.HiveUtil;
import net.sf.json.JSONArray;
@WebServlet("/DataSourceServlet")
public class DataSourceServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DataSourceServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
// 获取数据库名
String databaseName = request.getParameter("databaseName");
HiveUtil hiveUtil = new HiveUtil();
// 通过数据库名切换数据库
hiveUtil.changeDatabase(databaseName);
// 获得表集合
List list = hiveUtil.getTableList();
for (String line : list) {
System.out.println(line);
}
// 将结果作为json数组传回到页面
String result = JSONArray.fromObject(list).toString();
out.print(result);
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
待实现功能:点击预览数据能获得表内的前十条数据,点击结构信息能获得表结构信息,并且都是在当前页面展示