HiveUtil

package com.anna.hive.util;

import java.sql.*;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;

/**
 * 1. 數據倉庫連接
 * 2. 數據庫列表預覽
 * 3. 數據表列表預覽
 * 4. 數據表結構預覽
 * 5. 樣例數據預覽(抽樣)
 * 6. 切換數據庫
 * */

public class HiveUtil {
    private Connection conn = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    Statement statement = null;

    static {
        try{
            //1、加載驅動
            Class.forName("org.apache.hive.jdbc.HiveDriver");
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    //構造方法:打開一個連接
    public HiveUtil(){
        try{
            //1、數據倉庫連接
            conn = DriverManager.getConnection("jdbc:hive2://master:10010","anna","");
            statement = conn.createStatement();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 2. 數據庫列表預覽
     * @return 返回數據庫名稱集合
     * 語句:show databases
     */
    public List<String> getDatabases(){
        List result = new ArrayList<String>();

        //執行查詢
        try {
            preparedStatement = conn.prepareStatement("show databases");
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                result.add(resultSet.getString(1));
            }
            return result;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
    * 3、數據庫列表預覽
    * show tables
    * @param database 要獲取哪個數據庫中的表
    * @return 返回的是數據表的集合
     * 語句:show {database}.{table}
    * */
    public List<String> getTables(String database){
        List result = new ArrayList<String>();

        //執行查詢
        try {
            //切換數據庫
            changeDatabase(database);
            resultSet = statement.executeQuery("show tables");
            while (resultSet.next()) {
                result.add(resultSet.getString(1));
            }
            return result;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 4、 數據表結構預覽
     * @param database 數據庫名稱
     * @param table 數據表名稱
     * @return 返回的是表的描述性息的集合
     * 語句:desc {database}.{table}
     * */
    //需要參數:數據庫名,表名
    public List<String> getTableDesc(String database,String table){
        List<String> result = new ArrayList<>();

       try{
           //創建preparedStatement
           preparedStatement = conn.prepareStatement("desc " + database + "." + table);
           //執行查詢操作
           ResultSet resultSet = preparedStatement.executeQuery();

           //將結果封裝到list中
           while (resultSet.next()) {
               result.add(resultSet.getString(1) + "  " + resultSet.getString(2));
           }

           return result;

       } catch (SQLException e) {
           e.printStackTrace();
       }
       return null;
    }

    /**
     * 5. 樣例數據預覽(抽樣)——>limit實現
     * @param database 數據庫名稱
     * @param table 數據表名稱
     * @param n 獲取前n行記錄
     * 語句:select * from {database}.{table} limit {number}
     * */
    public List<String> getDataByLimit(String database, String table, int n) {
        int columns = getTableDesc(database, table).size();
        List<String> list = new ArrayList<>();
        try {
            preparedStatement = conn.prepareStatement("select * from " + database + "." + table + " limit " + n);
            resultSet = preparedStatement.executeQuery();
            return getData(resultSet, columns);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 5. 樣例數據預覽(抽樣)——> tablesample實現
     * @param database 數據庫名稱
     * @param table 數據表
     * @param percent 抽樣比例
     * 語句: select * from {database}.{table} tablesample({percent} percent)
     * */
    public List<String> getDataBySample(String database, String table, double percent) {
        int columns = getTableDesc(database, table).size();
        List<String> list = new ArrayList<>();
        try {
            preparedStatement = conn.prepareStatement("select * from " + database + "." + table + " tablesample(" + percent + " percent)");
            resultSet = preparedStatement.executeQuery();
            return getData(resultSet, columns);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 5. 樣例數據預覽(抽樣)——> rand實現
     * @param database 數據庫名稱
     * @param table 數據表
     * @param n 隨機取出前n行記錄
     * 語句:select *,rand()r from {database}.{table} order by r limit n
     * */
    public List<String> getDataByRandom(String database, String table, int n) {
        int columns = getTableDesc(database, table).size();
        List<String> list = new ArrayList<>();
        try {
            preparedStatement = conn.prepareStatement("select *,rand() r from " + database + "." + table + " order by r limit " + n);
            resultSet = preparedStatement.executeQuery();
            return getData(resultSet, columns - 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 數據封裝工具
     * @param resultSet 結果集
     * @param size 數據列數量,也就是要獲取幾列的數據
     * @return 封裝的List數據集
     */
    private List<String> getData(ResultSet resultSet,int size){
        try {
            List<String> list = new ArrayList<>();
            while (resultSet.next()) {
                String line = "";
                for (int i = 0; i < size; i++) {
                    line += resultSet.getString(i + 1) + "\t";
                }
                line = line.substring(0, line.length() - 1);        //左閉右開
                //將每一條記錄添加到lisi中
                list.add(line);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 通過自定義的SQL返回結果
     * @param sql 要執行的sql語句——包含數據庫名稱
     * @return 執行SQL的結果集
     *
     * 前期準備:hive中存在數據庫temp,用于存放臨時SQL去查詢的中間表
     * ① 將查詢到的結果集生成中間表存放到temp數據庫下 create table {table} as sql
     * ② 再通過查詢此中間表返回結果集合
     * ③ 表名隨機:tmp_userId_時間戳
     * */
    public List<String> getDataBySQL(String sql) {
        //將表名進行隨機:tmp_userId_時間戳
        //時間戳——> long ——> 1970-01-01 00:00:00 ——> Unix元年

        try {
            String tableName = "temp_1_" + new Date().getTime();
            preparedStatement = conn.prepareStatement("create table temp." + tableName + " as " + sql);
            preparedStatement.execute();

            //獲取表的字段個數
            int size = getTableDesc("temp",tableName).size();
            preparedStatement = conn.prepareStatement("select * from temp." + tableName);
            ResultSet resultSet = preparedStatement.executeQuery();
            return getData(resultSet, size);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 從數據表中查詢指定列的數據
     * @param sql 要執行的sql語句——>包含數據庫名稱
     * @param columnsIndex 待查詢的列的索引
     * @return SQL執行的結果集
     * */
    public List<String> getDataBySQLWithColumns(String sql,int[] columnsIndex){
        try{
            String tableName = "tmp_1_" + new Date().getTime();
            preparedStatement = conn.prepareStatement("create table temp." + tableName + " as " + sql);
            resultSet = preparedStatement.executeQuery();
            return getDataByColumns(resultSet, columnsIndex);

        }catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param resultSet 查詢結果集
     * @param columnIndex 數據列索引
     * @return 封裝的List數據集
     * */
    private List<String> getDataByColumns(ResultSet resultSet, int[] columnIndex) {
        List<String> list = new ArrayList<>();

        try{
            while (resultSet.next()) {
                String line = "";

                for (int i = 0;i < columnIndex.length;i++) {
                    line += resultSet.getString(columnIndex[i]) + ",";
                }
                line = line.substring(0,line.length() - 1);
                list.add(line);
            }
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 執行查詢語句,返回結果
     * @param sql 需要執行的sql語句
     * @param paras 執行查詢時所需要的參數
     * @return 結果集
     * */
    public ResultSet executeQuery(String sql,Object[] paras){
        try {
            preparedStatement = conn.prepareStatement(sql);
            getPreparedStatement(paras);
            return preparedStatement.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 將傳入的參數進行賦值,構建一個完整的PreparedStatement
     * @param paras 傳入的參數
     */
    private void getPreparedStatement(Object[] paras) {
        try {
            if (paras != null) {
                for (int i = 0; i < paras.length; i++) {
                    preparedStatement.setObject(i + 1, paras[i]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 執行一個不需要返回結果的命令
     * @param sql 需要執行的sql
     * @param paras 執行sql需要的參數
     */
    public void execute(String sql, Object[] paras){
        try {
            preparedStatement = conn.prepareStatement(sql);
            getPreparedStatement(paras);
            preparedStatement.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 6、切換數據庫
     * @param database 數據庫名稱
     * 語句:use {database}
     * */
    public void changeDatabase(String database) {
        try {
            statement.execute("use " + database);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 釋放資源
     */
    public void close() {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (preparedStatement != null){
                preparedStatement.close();
            }
            if (conn != null){
                conn.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容

  • 特奧蒂瓦坎古城,是印第安文明的重要遺址,位于墨西哥首都墨西哥城東北約40公里處。 據說,在其繁榮興盛的六、七世紀,...
    東燕川閱讀 322評論 0 0
  • 民間借貸一般發生在熟人之間,前面小編也講過借條的寫法,但是借條有時候利息是口頭約定的,沒有書面寫到借條或者借款合同...
    0234785bfc90閱讀 651評論 0 0
  • 最近,學校發了通知,如果還想要畢業證,就趕緊聯系老師。我的學分不夠畢業,且我記得大三的時候我把重修的科目所需要的報...
    橙子在陽光下閱讀 219評論 0 0
  • 31.太陽再怎么努力燃燒,都無法照亮昏暗的時間。在無邊的黑暗里,你是黎明的光。 32.我見到她時,花兒已經謝了。花...
    逆行的水星閱讀 307評論 9 6