0


hive表 desc 描述元信息获取(java hive jdbc)

1、前言

在hive的开发交互中,有时需要获取hive表数据在hdfs中的location位置、或者获取hive的文件存储格式使用的压缩算法甚至是表中的字段类型字段注释字段约束、表中是否有数据、数据大小、文件数等信息。这些信息hive没有提供统一的入口,即使直连hive元数据存储的mysql数据库,也很难一次性拿到这些数据。

但是hive提供的desc命令则可以一次性获取所有的这些信息,例如:

desc formatted tableName

(注:我这里用的是2.3.9版本,加不了约束,所以详细信息里面看不到约束)

不过,虽然desc可以一次性获取所有的这些信息,但是这些信息并不是封装好的,需要通过resultSet一行行读取。以前为了获取hive表存储地址,我解析过一次,但那个不够通用。所以这次准备封装一个通用的解析,避免自己重复造轮子。

2、解析代码

    public static Map<String, Object> getTableInfo(ResultSet resultSet) throws Exception {
        Map<String, Object> result = new HashMap<>();

        // 定义多个集合用于存储hive不同模块的元数据
        Map<String, String> detailTableInfo = new HashMap<>();
        Map<String, String> tableParams = new HashMap<>();
        Map<String, String> storageInfo = new HashMap<>();
        Map<String, String> storageDescParams = new HashMap<>();
        Map<String, Map<String, String>> constraints = new HashMap<>();
        List<Map<String, String>> columns = new ArrayList<>();
        List<Map<String, String>> partitions = new ArrayList<>();

        Map<String, String> moduleMap = getDescTableModule();

        // 解析resultSet获得原始的分块数据
        String infoModule = "";
        while (resultSet.next()) {

            String title = resultSet.getString(1).trim();

            if (("".equals(title) && resultSet.getString(2) == null) || "# Constraints".equals(title)) continue;

            if (moduleMap.containsKey(title)) {
                if ("partition_info".equals(infoModule) && "col_name".equals(moduleMap.get(title))) continue;
                ;
                infoModule = moduleMap.get(title);
                continue;
            }

            String key = null;
            String value = null;
            switch (infoModule) {
                case "col_name":
                    Map<String, String> map = new HashMap<>();
                    int colNum = resultSet.getMetaData().getColumnCount();
                    for (int col = 0; col < colNum; col++) {
                        String columnName = resultSet.getMetaData().getColumnName(col + 1);
                        String columnValue = resultSet.getString(columnName);
                        map.put(columnName, columnValue);
                    }
                    columns.add(map);
                    break;

                case "table_info":
                    key = resultSet.getString(1).trim().replace(":", "");
                    value = resultSet.getString(2).trim();
                    detailTableInfo.put(key, value);
                    break;

                case "table_param":
                    key = resultSet.getString(2).trim().replace(":", "");
                    value = resultSet.getString(3).trim();
                    tableParams.put(key, value);
                    break;

                case "storage_info":
                    key = resultSet.getString(1).trim().replace(":", "");
                    value = resultSet.getString(2).trim();
                    storageInfo.put(key, value);
                    break;

                case "storage_desc":
                    key = resultSet.getString(2).trim().replace(":", "");
                    value = resultSet.getString(3).trim();
                    storageDescParams.put(key, value);
                    break;

                case "not_null_constraint":
                    Map<String, String> notNullMap = constraints.getOrDefault("notnull", new HashMap<>());
                    if ("Table:".equals(title.trim())) resultSet.next();

                    String notNullConstraintName = resultSet.getString(2).trim();
                    resultSet.next();

                    key = resultSet.getString(2).trim();
                    notNullMap.put(key, notNullConstraintName);

                    constraints.put("notnull", notNullMap);
                    break;

                case "default_constraint":
                    Map<String, String> defaultMap = constraints.getOrDefault("default", new HashMap<>());
                    if ("Table:".equals(title.trim())) resultSet.next();

                    String defaultConstraintName = resultSet.getString(2).trim();
                    resultSet.next();

                    key = resultSet.getString(1).trim().split(":")[1];
                    value = resultSet.getString(2).trim();
                    int valueIndex = value.indexOf(":");
                    value = value.substring(valueIndex + 1);

                    defaultMap.put(key + "_constraintName", defaultConstraintName);

                    constraints.put("default", defaultMap);
                    break;

                case "partition_info":
                    Map<String, String> partitionMap = new HashMap<>();
                    int partitionColNum = resultSet.getMetaData().getColumnCount();
                    for (int col = 0; col < partitionColNum; col++) {
                        String columnName = resultSet.getMetaData().getColumnName(col + 1);
                        String columnValue = resultSet.getString(columnName);
                        partitionMap.put(columnName, columnValue);
                    }
                    partitions.add(partitionMap);
                    break;

                default:
                    System.out.print("unknown module,please update method to support it : " + infoModule);
            }

        }

        result.put("columns",columns);
        result.put("detailTableInfo",detailTableInfo);
        result.put("tableParams",tableParams);
        result.put("storageInfo",storageInfo);
        result.put("storageDescParams",storageDescParams);
        result.put("constraints",constraints);
        result.put("partitions",partitions);

        return result;
    }

    private static Map<String, String> getDescTableModule() {
        Map<String, String> descTableModule = new HashMap<>();

        descTableModule.put("# col_name", "col_name");
        descTableModule.put("# Detailed Table Information", "table_info");
        descTableModule.put("Table Parameters:", "table_param");
        descTableModule.put("# Storage Information", "storage_info");
        descTableModule.put("Storage Desc Params:", "storage_desc");
        descTableModule.put("# Not Null Constraints", "not_null_constraint");
        descTableModule.put("# Default Constraints", "default_constraint");
        descTableModule.put("# Partition Information", "partition_info");

        return descTableModule;
    }

上面的代码基本上覆盖了所有常用的数据模块,如果有代码中没解析到的模块,则依据代码逻辑添加对应的模块名称和case模块即可。代码很简单,主要就是解析时要细心。

3、测试

下面是我新建的一个简单测试demo,有兴趣的可以简单看下:

1)引入依赖

        <!--    hive-jdbc    -->
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>2.3.9</version>
        </dependency>

2)编辑代码

    public static void main(String[] args) {
        try {
            String driverName = "org.apache.hive.jdbc.HiveDriver";
            Class.forName(driverName);
            Connection conn = DriverManager.getConnection("jdbc:hive2://192.168.71.135:10000/test_db");

            String sql = "desc formatted test_table";

            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet resultSet = ps.executeQuery();

            Map<String,Object> result = getTableInfo(resultSet);

            System.out.println(result.size());

        } catch (Exception throwables) {
            throwables.printStackTrace();
        }
    }

3)结果显示

可以看到除了约束之外,其它的数据都正常的存入到了对应的集合中。(我测试用的2.3.9版本的约束创建有问题,但是在3.1.0版本中创建约束是正常的)。

4、总结

上面是我根据自己的需求使用进行的代码编辑,其基本包含了全部的表信息。但是也有可能有没考虑周到的地方,比如我一开始没考虑到多个同种约束的问题,在使用中遇到问题了又来重新更新了文章中的代码。所以如果使用中有些地方解析不对,可能需要您根据自己的实际场景再进行改写。

标签: hive 大数据 java

本文转载自: https://blog.csdn.net/Interest1_wyt/article/details/128259279
版权归原作者 Interest1_wyt 所有, 如有侵权,请联系我们删除。

“hive表 desc 描述元信息获取(java hive jdbc)”的评论:

还没有评论