
# Impala开发规则
#### Hive JDBC驱动的加载
客户端程序以JDBC的形式连接Impalad时，需要首先加载Hive的JDBC驱动类org.apache.hive.jdbc.HiveDriver。
所以在客户端程序开始前，必须先使用当前类加载器加载该驱动类。
如果classpath下没有相应的jar包，则客户端程序抛出Class Not Found异常并退出。
如下：
```
Class.forName("org.apache.hive.jdbc.HiveDriver").newInstance();
```
#### 获取数据库连接
使用JDK的驱动管理类java.sql.DriverManager来获取一个Impalad的数据库连接。
Impalad的数据库URL为url="jdbc:hive2://xxx.xxx.xxx.xxx:21050;auth=noSasl;principal=impala/hadoop.hadoop.com@HADOOP.COM;user.principal=impala/hadoop.hadoop.com;user.keytab=conf/impala.keytab";
以上已经经过安全认证，所以用户名和密码为null或者空。
// 建立连接
```
connection = DriverManager.getConnection(url, "", "");
```
#### 执行Impala SQL
执行Impala SQL，注意Impala SQL不能以";"结尾。
**正确示例：**
```
String sql = "SELECT COUNT(*) FROM employees_info";
Connection connection = DriverManager.getConnection(url, "", "");
PreparedStatement statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
```
**错误示例：**
```
String sql = "SELECT COUNT(*) FROM employees_info;";
Connection connection = DriverManager.getConnection(url, "", "");
PreparedStatement statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
```
#### Impala SQL语法规则之判空
判断字段是否为"空"，即没有值，使用"is null"；判断不为空，即有值，使用"is not null"。
要注意的是，在Impala SQL中String类型的字段若是空字符串， 即长度为0，那么对它进行is null的判断结果是False。此时应该使用"col = '' "来判断空字符串；使用"col != '' "来判断非空字符串。
**正确示例：**
```
select * from default.tbl_src where id is null;
select * from default.tbl_src where id is not null;
select * from default.tbl_src where name = '';
select * from default.tbl_src where name != '';
```
**错误示例：**
```
select * from default.tbl_src where id = null;
select * from default.tbl_src where id != null;
select * from default.tbl_src where name is null;
select * from default.tbl_src where name is not null;注：表tbl_src的id字段为Int类型，name字段为String类型。
```
#### 多线程安全登录方式
如果有多线程进行login的操作，当应用程序第一次登录成功后，所有线程再次登录时应该使用relogin的方式。
login的代码样例：
```
private Boolean login(Configuration conf){
    boolean flag = false;
    UserGroupInformation.setConfiguration(conf);
    
    try {
      UserGroupInformation.loginUserFromKeytab(conf.get(PRINCIPAL), conf.get(KEYTAB));
      System.out.println("UserGroupInformation.isLoginKeytabBased(): " +UserGroupInformation.isLoginKeytabBased());
      flag = true;
    } catch (IOException e) {
      e.printStackTrace();
    }
    return flag;
    
  }
```
relogin的代码样例：
```
public Boolean relogin(){
        boolean flag = false;
        try {
            
          UserGroupInformation.getLoginUser().reloginFromKeytab();
          System.out.println("UserGroupInformation.isLoginKeytabBased(): " +UserGroupInformation.isLoginKeytabBased());
          flag = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }
```
#### 避免对同一张表同时进行读写操作
目前的版本中，Hive不支持并发操作，需要避免对同一张表同时进行读写操作，否则会出现查询结果不准确，甚至任务失败的情况。
