HIVE客户端简单API
write by donaldhan, 2020-03-05 23:11引言
我们先来回顾一下上一篇HIVE DDL&DML简介所讲内容。 如果创建数据库时没有指定对应的数仓存储路径,默认为HDFS下的数仓目录user/hive/warehouse+数据库名+.db对应的文件夹。 如果数据库中有0或多个表时,不能直接删除,需要先删除表再删除数据库;如果想要删除含有表的数据库,在删除时加上cascade,可以级联删除(慎用)。 Hive表有两种,分别是内部表与外部表,如果是内部表,在删除时,MySQL中的元数据和HDFS中的数据都会被删除; 如果是外部表,在删除时,MySQL中的元数据会被删除,HDFS中的数据不会被删除; 加载文件数据到Hive表有两种方式,一种是从本地文件加载,一种从hdfs文件加载。如果加上LOCAL表示从本地加载数据, 默认不加,从hdfs中加载数据,添加OVERWRITE关键字,将会覆盖表中数据,及先删除,在加载。 从hdfs方式加载完数据,需要注意hdfs上的文件将会被删除,移动hdfs的垃圾箱中。 插入数据实际为一个MR任务。聚合类的操作(max,min,avg,count),都需要运行MR任务。 导出数据与加载数据LOCAL和OVERWRITE使用基本一致。如果加上LOCAL表示导出到本地默认不加,导出到hdfs,如果加OVERWRITE关键字,将会覆盖原文件中的数据,及先删除,在导出。 从本地加载文件到分区表时,实际上是,将本地文件放到hdfs上的数据库分区表文件夹(order_partition)下的分区字段+分区Value(event_month=2020-02)文价夹。 单级分区和多级分区唯一的区别就是多级分区在hdfs中的目录为多级。
今天我们来看一下client api的使用。
目录
从搜索的结果来看,hive client API相关的文章,在大数据的场景中,应该没有这种java直接访问hive,要结合spark、今天我们只做一个简单的测试。 HIVE环境我们使用的是单机版的,具体参考下文:
添加依赖
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.1.0</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
测试DEMO
具体测试代码如下
package com.hive.jdbc.client;
import groovy.util.logging.Slf4j;
import org.mortbay.log.Log;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author revanthreddy
* 使用前,启动hiveserver2
*/
@Slf4j
public class HiveJdbcClient {
private static final String DRIVER_NAME = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException {
try {
Class.forName(DRIVER_NAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
Connection con = DriverManager.getConnection("jdbc:hive2://pseduoDisHadoop:10000/test", "hadoop", "123456");
Statement stmt = con.createStatement();
String tableName = "student";
stmt.execute("DROP TABLE " + tableName);
String query = "CREATE TABLE student (id int,name string,tel string,age int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\\t'";
stmt.execute(query);
// show tables
String sql = "show tables";
Log.info("Running Query : {}" ,sql);
ResultSet res1 = stmt.executeQuery(sql);
if (res1.next()) {
System.out.println(res1.getString(1));
}
// describe table
sql = "describe " + tableName;
Log.info("Running Query : {}" + sql);
res1 = stmt.executeQuery(sql);
while (res1.next()) {
System.out.println(res1.getString(1) + "\t" + res1.getString(2));
}
// load data into table , 这里使用的是本地文件加载数据方式
String filepath = "/bdp/hive/hiveLocalTables/student.txt";
sql = "load data local inpath '" + filepath + "' into table " + tableName;
Log.info("Running Query :{} " ,sql);
stmt.execute(sql);
// select * query
String sqlquery = "select * from " + tableName;
Log.info("Running Query :{} " ,sqlquery);
ResultSet res2 = stmt.executeQuery(sqlquery);
while (res2.next()) {
Log.info(String.valueOf(res2.getInt(1)) + "\t" + res2.getString(2));
}
}
}
在测试前,要先启动HiveServer2, 应为我们使用的JDBC方式连接HIVE。
注意我们的LOG使用的是import groovy.util.logging.Slf4j; 而不是LOMBOK。
本文中的代码可以从下面的仓库中拉去。
HiveMetaStoreClient:https://github.com/Donaldhan/HiveMetaStoreClient
附
引用文献
使用hive客户端java api读写hive集群上的信息:https://www.bbsmax.com/A/1O5EBAy7d7/
hdinsight-java-hive-jdbc:https://github.com/Azure-Samples/hdinsight-java-hive-jdbc
HiveMetaStoreClient:https://github.com/Re1tReddy/HiveMetaStoreClient
org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:286)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: org.apache.hadoop.hive.ql.parse.ParseException:line 1:108 cannot recognize input near ';' '<EOF>' '<EOF>' in serde properties specification
at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:211)
at org.apache.hadoop.hive.ql.parse.ParseUtils.parse(ParseUtils.java:77)
at org.apache.hadoop.hive.ql.parse.ParseUtils.parse(ParseUtils.java:70)
at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:468)
at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1317)
at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1295)
at org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:204)
... 15 more
Disconnected from the target VM, address: '127.0.0.1:54934', transport: 'socket'
Process finished with exit code 1
这个是由于我的SQL语句多一个的一个分号;
String query = "CREATE TABLE student (id int,name string,tel string,age int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\\t';";
String query = "CREATE TABLE student (id int,name string,tel string,age int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\\t'";
ERROR StatusLogger No log4j2 configuration file found
原因,log4j2只支持xml和json两种格式的配置,所以配置log4j.properties是没有作用的。要把log4j.properties的文件改为log4j2.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
</Console>
<RollingFile name="RollingFile" filename="log/hiveMetaStore.log"
filepattern="%d{yyyy-MM-dd}.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
<Policies>
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
<DefaultRolloverStrategy max="20" />
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile" />
</Root>
</Loggers>
</Configuration>