**
动态加载hive-jdbc
**
应用场景:
由于hive-jdbc的版本一般不具有向下兼容性,所以当我们需要从不同hadoop集群取hive数据的时候,考虑动态去加载不同版本的hive-jdbc驱动。
亲测版本:hive-jdbc-1.1.0
集群版本:CDH5.13.2 (hadoop-2.6.0)
相关jar包:
package com.zcah.healthScan.common;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.*;
import java.util.*;
public class SwitchJDBCUtil {
/**
* 方法名称 :getCon
* 创 建 人 :lsy
* 创建日期 :2018-11-8 17:39:00
* 功能说明 :获取jdbc的连接对象
* @return jdbc的连接对象
*/
public Connection getCon(String url,String driverName,String userName,String password,String dictory) throws Exception{
//动态加载jar包
//File file = new File(dictory);
File file = new File("/usr/local"+dictory);
System.out.println("hive-jdbc的jar文件在服务器的存储路径:"+file.getPath());
//得到该目录下的所有的jar文件
File[] listFiles = file.listFiles();
//创建一个set集合用于存储驱动文件的url,使得url不能重复
Set<URL> set = new HashSet<URL>();
//遍历所有的文件
for (File file2 : listFiles) {
File fileTemp=new File(file,file2.getName());
System.out.println("文件名:"+file2.getName());
set.add(fileTemp.toURI().toURL());
System.out.println(fileTemp.toURI().toURL());
}
//将集合给转换为数组
URL[] urls = set.toArray(new URL[20]);
//单个jar文件加载
//URLClassLoader loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
//多个jar文件加载 本地IDEA环境可用 部署到服务器上不可用
//URLClassLoader loader = new URLClassLoader(urls);
//服务器上 获取当前线程 调用 上下文类加载器 亲测 可行
URLClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
System.out.println(loader);
System.out.println(file.toURI().toURL());
Class cls = loader.loadClass(driverName);
//实例化driver对象
Driver driver = (Driver) cls.newInstance();
Properties info = new Properties();
info.setProperty("user", userName);
info.setProperty("password",password);
//获取连接对象
Connection connect = null;
try {
connect = driver.connect(url, info);
} catch (SQLException e) {
e.printStackTrace();
System.out.println("连接hive失败:"+e.getMessage());
}
System.out.println("连接hive成功!");
return connect;
}
/**
* 方法名称 :通过main方法测试
* 创 建 人:lsy
* 创建日期 :2018-11-8 18:00:00
* 功能说明 :测试连接是否成功
* @return
*/
public static void main(String[] args) throws Exception {
SwitchJDBCUtil jdbc = new SwitchJDBCUtil();
// HiveQueryResultSet res;
ResultSet res;
Connection conn = null;
Statement stmt = null;
String sql = "show databases";
//mysql测试
//Connection con = jdlc.getCon("jdbc:mysql://192.168.101.194:3306/test", "com.mysql.jdbc.Driver", "root", "root","D:/mysqljar");
conn = jdbc.getCon("jdbc:hive2://192.168.101.8:10000/", "org.apache.hive.jdbc.HiveDriver","hive","hive","C:\\Users\\Administrator\\Desktop\\test-hive1.1.0");
stmt = conn.createStatement();
//res = (HiveQueryResultSet) stmt.executeQuery(sql);
res = stmt.executeQuery(sql);
List<List> list = new ArrayList<>();
while (res.next()) {
System.out.println(res.getString(1));
}
}
总结:
个人感觉有三点需要注意:
1.使用动态加载hive-jdbc时,本地porm.xml中需要将hive-jdbc的依赖注释掉!!!否则如果porm中的hive-jdbc版本与集群上的hive版本不匹配的报错信息。
2.测试过程中hive-jdbc所需要的jar包是通过查看hive的maven依赖后手动去本地maven库中取出的,但是maven依赖中并没有看出需要hadoop-client-xxx.jar 和 hadoop-common-xxx.jar (hadoop-client-2.5.2.jar 、hadoop-common-2.6.5.jar)。
3.ClassLoader类加载器的问题:
*多个jar文件加载 本地IDEA环境可用 部署到服务器上不可用
URLClassLoader loader = new URLClassLoader(urls);//服务器上不可用
*服务器上 要获取当前线程 调用 上下文类加载器 亲测 可行
URLClassLoader loader = new URLClassLoader(urls,Thread.currentThread().getContextClassLoader());
版权声明:本文为博主原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/LSY929981117/article/details/107714001