hive的(ql)hql使用和基於UDF的用法;以及java對hive的遠端訪問
阿新 • • 發佈:2018-11-02
1>hive下建立表並匯入資料
(資料可以是本地的,也可以是hdfs上的)
>建立本地檔案 [[email protected] /]# vi student 1,xiaoming 2,xiaohong 3,xiaogang 4,tom 5,tim >hive下建立表;desc table;檢視自己建立的表結構 create table t1(id int,name String) row format delimited fields terminated by ',';
>將本地檔案匯入表中 load data local inpath'/student' into table t1;
>每次上傳同一個資料到同一個表中,會自動拷貝一份,所以可以使用overwrite
load data local inpath '/student' overwrite into table t1;
>查看錶中資料: select * from t1;
>統計表裡面一共有多少條記錄;
select count(id) from t1; #執行的時候執行在mapredurce上
>刪除表
drop table t1;
2>內部表與外部表
外部表和 內部表 在元資料的組織上是相同的,而實際資料的儲存則有較大的差異 內部表 的建立過程和資料載入過程(這兩個過程可以在同一個語句中完成),在載入 資料的過程中,實際資料會被移動到資料倉庫目錄中;之後對資料對訪問將會直接在資料倉 庫目錄中完成。刪除表時,表中的資料和元資料將會被同時刪除
外部表 只有一個過程,載入資料和建立表同時完成,並不會移動到資料倉庫目錄中, 只是與外部資料建立一個連結。當刪除一個 外部表 時,僅刪除該連結
>建立內部表步驟如上,相比缺少了external關鍵字的使用
>建立外部表
create external table t2 (id int,name String) row format delimited fields
terminated by ',';
3>建立分割槽表
把不同型別的資料放到不同的目錄下;
1>建立分割槽表
create table t3 (id int,name String ) partitioned by (subid int ) row format delimited fields terminated by ',';
2>向表中插入資料
load data local inpath '/student' into table t3 partition(subid=1) ;
load data local inpath '/student2' overwrite into table t3 partition(subid=2) ;
3>查詢分割槽:
hive> show partitions t3;
4>查詢分割槽的某個檔案
select * from t3 where subid=2;
效果如圖:t3這個目錄中含有兩個不同的資料表,查詢的時候可以提高效率
4>基於UDF對錶中資料的查詢操作:
寫一個類繼承與hive的UDF類,寫一個方法,必須是evaluate,支援過載
package com.zhiyou.han.udf; import java.util.HashMap; import java.util.Map; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public class MyUDF extends UDF{ private static Map<String, String> map= new HashMap<String, String>(); static { map.put("xiaoming", "小明");
map.put("xiaohong", "小紅"); } public static Text evaluate(Text name) { String getName = name.toString(); String chainName = map.get(getName); if(chainName==null) { chainName = "null"; } return new Text(chainName); } }
>將這個類到處jar包上傳liunx下 /注意jar包的地址
hive> add jar /U.jar;
>命名臨時函式名:
hive> create temporary function U as 'com.zhiyou100.udf.MyUDF';
>平常查出結果是這樣的
hive> select id ,name from t1;
OK
1 xiaoming
2 xiaohong
3 xiaogang
>使用UDF查詢後
hive> select id ,U(name) from t1;
OK
1 小明
2 小紅
3 無名
>銷燬臨時的函式
hive> drop temporary function U;
>刪除jar包
hive> delete jar /U.jar
5>使用java遠端訪問liunx下的hive
1>與jdbc的執行流程是一樣的
jdbc的執行流程:
1.載入驅動
2.建立連線
3.準備sql
4.執行sql
5.處理結果
6.釋放資
2>liunx下啟動hive的遠端服務:
>啟動遠端服務: #hive --service hiveserver //版本1的 #hive hiveserver2 //版本2的
>啟動過程中在liunx下使用命令連線看是否能成功連線上
beeline -u jdbc:hive2://ip:10000/資料庫名 IP 可以寫自己的主機名或是自己的主機的IP地址
>報錯如下
>出現root is not allowed tp (state=08S01,code=0)
需要在hadoop配置檔案下core-site.xml檔案中加入如下程式碼: 然後停止(stop-all.sh)hadoop,在啟動(start-all.sh)hadoop,其中不需要預格式化,然後重新啟動hive(直接輸入hive)
<property> <name>hadoop.proxyuser.root.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.root.groups</name> <value>*</value> </property>
>如果報錯: inode="tmp/hive" root:supergroup:drwx---- 是因為許可權的問題
執行一下該命令 hdfs dfs -chmod -R 777 /tmp/
3>執行完上述步驟,保證可以遠端訪問:
然後寫java程式碼如下:
package com.zhiyou.han.hiveApi; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import org.apache.hadoop.io.Text; import com.zhiyou.han.udf.MyUDF; public class HiveApi { // 要求必須liunx下hive開啟遠端服務,和訪問本地的的mysql資料庫一個原理 public static void main(String[] args) throws Exception { // 1.載入驅動 Class.forName("org.apache.hive.jdbc.HiveDriver"); // 2.建立連線,輸入自己的IP,且埠號為 1000 String url = "jdbc:hive2://192.168.188.130:10000/default"; String user = "root"; String password = "root"; Connection conn = DriverManager.getConnection(url, user, password); // 3.準備sql語句 String sql = "select id,name from t2"; PreparedStatement ps = conn.prepareStatement(sql); // 4.執行sql語句 ResultSet rs = ps.executeQuery(); // 5.處理結果 while (rs.next()) {
//這部分可以自己發揮寫,只要資料對照資料庫中的名字就行 System.out.println(rs.getInt("id") + "\t" + MyUDF.evaluate(new Text(rs.getString("name")))); } // 6.釋放資源 rs.close(); ps.close(); conn.close(); } }