跳转至

广电用户数据存储与 处理的程序开发

任务背景

Hive与一般数据仓库使用传统关系数据库作为基础平台不同,Hive基于Hadoop平台构建,这使得Hive天然具备大数据处理能力。 在之前的学习和实践中,使用Hive都是通过CLI的方式,该方式仅允许使用HQL执行查询等操作,并且该方式比较笨拙、单一。 其实Hive也提供了轻客户端的实现,通过HiveServer或HiveServer2,客户端可以在不启动CLI的情况下对Hive中的数据进行操作,两者都允许远程客户端使用多种编程语言如Java、Python向Hive提交请求,返回结果。 学习多种方式操作Hive中的数据,落实科教兴国战略。

本章主要介绍

  • 如何配置Hive远程服务,
  • 搭建Hive远程开发环境,
  • 通过案例实现广电数据的存储和广电用户数据的查询与处理,
  • 并在此过程中学习通过IDEA编程软件进行程序运行、调试的主要过程和方法。

  • 配置Hive远程服务

  • 搭建Hive远程连接环境
  • 编写程序实现广电数据的存储
  • 编写程序实现广电数据的查询与处理

任务描述

在Hive CLI中,一次只能运行一条HQL语句,对于单词、语句编写失误造成的运行失败也无法立刻修改,只能重新编写语句,因此效率偏低。 在编程类的软件中进行HQL语句的编写、运行,可以避免上述问题的出现。 为了实现Hive程序调用,需要提前配置和启动Hive远程服务。 本任务配置Hive远程服务HiveServer2。

配置Hive远程服务

Hive 0.10.0版本具有一个可选的组件HiveServer,用于为Hive提供一种允许客户端远程访问的服务。 HiveServer基于Thrift协议,故也称HiveServer为ThriftServer。 HiveServer支持跨平台、跨编程语言对Hive进行访问;由于HiveServer受Thrift接口限制,所以HiveServer不能处理多于一个客户端的并发请求。 为实现多用户并发访问,Hive 0.11.0版本重写HiveServer代码得到了HiveServer2。 HiveServer2支持多客户端的并发和认证,用于为客户端通过API(例如JDBC、ODBC等)访问Hive提供更好的支持。

配置并启动Hive远程服务的操作如下。 配置Hive远程连接属性。在master主节点执行命令“vim /usr/local/hadoop-3.1.4/etc/hadoop/core-site.xml”,打开core-site.xml文件,然后进入编辑模式,添加Hive远程服务的属性,Hive远程服务的属性内容,修改好后按Esc键,输入“:wq”并按Enter键保存退出。

<property>
    <name>hadoop.proxyuser.root.hosts</name>
    <value>*</value>
</property>
<property>
    <name>hadoop.proxyuser.root.groups</name>
    <value>*</value>
</property>
hadoop.proxyuser.root.hosts * hadoop.proxyuser.root.groups *

分发配置文件至各子节点。将core-site.xml文件使用scp命令发送给各子节点。

scp -r /usr/local/hadoop-3.1.4/etc/hadoop/core-site.xml slave1:/usr/local/hadoop-3.1.4/etc/hadoop/
scp -r /usr/local/hadoop-3.1.4/etc/hadoop/core-site.xml slave2:/usr/local/hadoop-3.1.4/etc/hadoop/
scp -r /usr/local/hadoop-3.1.4/etc/hadoop/core-site.xml slave3:/usr/local/hadoop-3.1.4/etc/hadoop/
启动Hive远程服务。启动Hadoop集群和MySQL服务后,启动Hive元数据库服务、HiveServer2远程服务,运行结果如下图。

cd /usr/local/hive-3.1.2/bin
hive --service metastore &  //启动Hive元数据服务
jps  //查看后台服务进程
nohup hive --service hiveserver2 &  //后台启动HiveServer2服务
jps  //查看后台服务进程

图片2

启动远程服务之前,要启动Hive元数据服务, 否则在后续连接Hive,执行一系列数据操作时,编程软件会提示“Connection refused: connect”的错误。

任务描述

IntelliJ IDEA简称IDEA,是Java等编程语言开发集成环境之一,该集成环境在智能代码助手、代码自动提示、重构、Java EE支持、各类版本工具(Git、SVN等)、JUnit、CVS整合、代码分析、创新的GUI设计等方面较为优秀。 本任务在IDEA上搭建Hive开发环境,并实现Hive远程连接测试。

创建IDEA开发项目

读者可到JetBrains公司的官方网站自行下载相关版本的IDEA编程软件安装包。 对于个人用户,可下载Community版(社区版)的IDEA编程软件安装包。 下载后,请按照指示进行安装。 本书统一使用“IntelliJ IDEA Community Edition 2021.3.3”版本。 IDEA默认选用英文界面运行,读者也可根据个人需求在插件管理中下载中文语言包。 为了描述方便,本书统一以英文界面进行讲解。

在安装好编程软件后,即可创建IDEA开发项目,创建流程如下。 打开编程软件IDEA,弹出欢迎界面,如下图,单击“New Project”按钮。

图片3

在“New Project”界面中选择“Maven”选项,在“Project SDK”下拉列表框中选择1.8版本的JDK,如下图,单击“Next”按钮。

图片4

将项目命名为“HiveJavaAPI”,并将该项目放置在D盘根目录下,如下图,单击“Finish”按钮。

图片5

项目创建完成后,会自动生成项目框架,如下图。

图片6

项目初始框架包含的项目元素如下表。

项目元素 说明
项目根目录 项目存储的本地目录,项目HiveJavaAPI的安装目录为D:\HiveJavaAPI
.idea节点 主要用于保存IDEA项目的相关信息
src节点 用于保存源代码(main目录)和测试代码(test目录)
External Libraries节点 用于保存使用到的外部库文件链接
Scratches and Consoles 可提供Scratch files和Scratch buffers这两种临时的编辑环境,在临时的编辑环境中,读者可以通过编写一些文本内容或一些代码片段,实现IDEA功能测试

图片7 项目具体结构如右图。

添加依赖

创建好项目后,需要在项目的pom.xml文件中添加Hive相关依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.
apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>HiveJavaAPI</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.1.4</version>
        </dependency>
        <!-- Hive-->
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.glassfish</groupId>
                    <artifactId>javax.el</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-runner</artifactId>
                </exclusion>
            </exclusions>
            <version>3.1.2</version>
        </dependency>
    </dependencies>
</project>
在pom.xml文档界面中,单击鼠标右键选择“Maven”命令,再选择“Reload project”命令,如右图,可立即加载依赖。 加载完成后,可在左边Project工具栏中单击“External Libraries”查看。

图片8

加载完成后,相关的依赖包会默认保存到系统用户目录下的.m2/repository子目录下,如下图。

图片9

手动加载MySQL驱动

在加载MySQL驱动前,需要在MySQL JAR包下载官网中提前下载驱动JAR包“mysql-connector-java-8.0.20.jar”,并将其复制到本地磁盘的“HiveJavaAPI连接驱动”目录下。 在创建好的IDEA项目里加载MySQL驱动的流程如下。 单击菜单“File”,选择“Project Structure”选项,在弹出的“Project Structure”界面中选择“Libraries”选项,单击加号“+”按钮,选择“Java”选项,如下图。

图片10

选择存放MySQL驱动JAR包的本地目录,定位到连接驱动的位置并选中,如下图,单击“OK”按钮。

图片11

在弹出的界面“Choose Modules”中选择“HiveJavaAPI”选项,如左图,然后单击“OK”按钮,返回到“Project Structure”界面后,如右图,单击“Apply”按钮,即可完成驱动加载。

图片13

图片12

添加驱动后的项目视图会显示加载的新驱动列表,如下图。

图片14

JDBC及其主要接口

JDBC是Java数据库连接(Java DataBase Connectivity)的缩写,它是一套用于执行SQL语句的Java API。应用程序可通过JDBC连接到关系数据库,并通过使用SQL语句完成数据库中数据的查询、新增、更新和删除等操作。 不同数据库处理数据的方式并不太相同,如果直接使用数据库厂商提供的访问接口操作数据库,那么应用程序的可移植性会变得较差。有了JDBC后,便可解决应用程序可移植性差的问题,因为JDBC要求各个数据库厂商按照统一的规范来提供数据库驱动。 在应用程序中由JDBC和具体的数据库驱动联系,所以读者不必直接与底层的数据库交互,使得代码的通用性更强。JDBC在应用程序与数据库之间起到桥梁作用,当应用程序使用JDBC访问特定的数据库时,需要通过不同的数据库驱动与不同的数据库进行连接,连接后即可对该数据库进行相应的操作。

Hive-JDBC驱动是专用于Hive的JDBC驱动,客户端可通过JDBC访问Hive。 8.2.3小节中已在pom.xml文件中添加了对JDBC驱动的依赖。 在开发JDBC驱动前,需要了解JDBC常用的API。 JDBC API主要位于java.sql包中,java.sql包定义了一系列访问数据库的接口和类,常用接口包括Driver、DriverManager、Connection、Statement、PreparedStatement、ResultSet等。

1.Driver接口

Driver接口是所有JDBC驱动必须实现的接口,该接口专门提供给数据库厂商使用。需要注意的是,在编写JDBC驱动时,必须将所使用的数据库驱动或类库加载至项目的Classpath中。 在进行Java开发时,程序员只需要根据程序使用的驱动类型,针对对应的Driver接口装载即可,Driver接口的方法如下表。

方法名称 功能描述
class.forName("sun.jdbc.odbc.jdbcOdbcDriver") 通过ODBC-JDBC驱动程序装载JDBC驱动
class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver") 通过MSSQL 2000数据库的JDBC驱动程序装载JDBC驱动
方法名称 功能描述
class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver") 通过MSSQL 2005数据库的JDBC驱动程序装载JDBC驱动
class.forName("com.mysql.cj.jdbc.Driver") 通过MySQL数据库的JDBC驱动程序装载JDBC驱动
class.forName("oracle.jdbc.driver.OracleDriver") 通过Oracle数据库的JDBC驱动程序装载JDBC驱动

2.DriverManager接口

DriverManager接口是JDBC提供的工具类,用于加载JDBC驱动、建立与数据库之间的连接。 DriverManager类中的方法都是静态方法,因此在程序中无须对DriverManager类中的方法进行实例化,直接通过类名即可调用。DriverManager接口的方法如下表。

方法名称 功能描述
static void registerDriver(Driver driver) 该方法用于向DriverManager注册给定的JDBC驱动
static Connection getConnection(String url, String user,String pwd) 该方法用于建立与数据库之间的连接,并返回表示连接的Connection对象

3.Connection接口

Connection接口的主要作用是与特定数据库进行连接,在连接上下文中执行SQL语句并返回结果。Connection接口的主要方法如下表。

方法名称 功能描述
public java.sql.DatabaseMetaData getMetaData() 该方法用于返回表示数据库的元数据的DatabaseMeta对象
Statement createStatement() 该方法用于创建将SQL语句发送至数据库的Statement对象
PreparedStatement prepareStatement(String sql) 该方法用于创建将参数化的SQL语句发送至数据库的PreparedStatement对象
CallableStatement prepareCall(String sql) 该方法用于创建调用数据库存储过程的CallableStatement对象

4.Statement接口

Statement接口用于执行静态SQL语句并返回所生成结果的对象,Statement接口对象可以通过Connection接口实例的createStatement()方法获得。Statement接口的主要方法如下表。

方法名称 功能描述
boolean execute(String sql) 该方法用于执行各种SQL语句,并返回BOOLEAN类型的值,如果值为true,那么表示所执行的SQL语句有查询结果,可以通过Statement接口的getResultSet()方法获得查询结果
int executeUpdate(String sql) 该方法用于执行SQL中的INSERT、UPDATE和DELETE语句,并返回INT类型的值,表示数据库中受该SQL语句影响的记录条数
ResultSet executeQuery(String sql) 该方法用于执行SQL中的SELECT语句,并返回表示查询结果的ResultSet对象

5.PreparedStatement接口

PreparedStatement接口是Statement接口的子接口,表示预编译的SQL语句的对象。该接口扩展了带有参数SQL语句的执行操作,应用该接口中的SQL语句可以使用占位符“?”代替参数,然后通过setXxx()方法为SQL语句的参数赋值。 PreparedStatement接口的主要方法如表所示。 | 方法名称 | 功能描述 | | --- | --- | | int executeUpdate() | 该方法用于执行SQL语句,SQL语句必须是DML语句或是无返回内容的SQL语句,如DDL语句 | | ResultSet executeQuery() | 该方法用于执行SQL查询,并返回ResultSet对象 | | void setInt(int parameterIndex, int x) | 该方法用于将指定参数设置成给定的INT值 | | void setString(int parameterIndex, String x) | 该方法用于将指定参数设置成给定的STRING值 |

6.ResultSet接口

ResultSet接口表示数据库查询的结果集,通常通过执行查询数据库的语句生成,主要用于保存JDBC执行查询时返回的结果。该结果集被封装在一个逻辑表格中,在ResultSet接口内部有一个指向表格数据行的游标。 ResultSet接口初始化时,游标默认指向第一行之前,可调用next()方法移动游标到下一行,直至下一行为空则返回FALSE。 ResultSet接口的主要方法如下表。

方法名称 功能描述
String getString(int columnIndex) 该方法用于获取指定字段的STRING类型的值,参数columnIndex代表字段的索引
String getString(String columnName) 该方法用于获取指定字段的STRING类型的值,参数columnName代表字段的名称

续上表 | 方法名称 | 功能描述 | | --- | --- | | int getInt(int columnIndex) | 该方法用于获取指定字段的INT类型的值,参数columnIndex代表字段的索引 | | int getInt(String columnName) | 该方法用于获取指定字段的INT类型的值,参数columnName代表字段的名称 | | boolean next() | 该方法用于将游标从当前位置向下移一行 |

创建连接测试程序

使用JDBC连接数据库时,通常需要提供如下4个必要参数。 驱动类名:“org.apache.hive.jdbc.HiveDriver”。 连接地址和端口号:“jdbc:hive2://master:10000”。 用户名:使用默认用户root。 密码:使用默认密码123456。

在IDEA中创建连接测试程序,实现连接Hive数据库并创建数据库test,操作如下。 创建Java类。选择main节点下面的java文件夹,单击鼠标右键选择“New”命令,选择“Java Class”命令,如下图。在弹出的界面输入“Connection”,按Enter键,创建新的Java类“Connection.java”。

图片15

编辑代码。在新建的Java类Connection.java中进行与Hive默认数据库DEFAULT的连接,并创建新的数据库test。

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.hive.jdbc.HiveDriver;

public class Connection {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String driver = "org.apache.hive.jdbc.HiveDriver";
        String url = "jdbc:hive2://master:10000/DEFAULT";
        String username = "root";
        String password = "123456";
        // 加载JDBC驱动
        Class.forName(driver);
        // 通过URL、用户名、密码建立与Hive数据库的连接
        java.sql.Connection connection = DriverManager.getConnection(url,
username,password);
        // 创建Statement对象
        Statement stmt = connection.createStatement();
        // 执行创建数据库test的SQL语句
        stmt.execute("CREATE DATABASE test");
        // 关闭Statement对象、Connection对象,释放资源
        stmt.close();
        connection.close();
    }
}
运行程序。在对应代码文件中,单击鼠标右键选择“Run 'Connection.main()'”命令运行代码,在下方工具栏“Run”运行结果出现“Process finished with exit code 0”表示运行无误,如下图。

图片16

验证。在Hive CLI,使用“SHOW DATABASES;”命令查询数据库,可以看到刚创建的数据库test,如下图。至此,Hive的开发环境搭建成功。

图片17

任务描述

在实现Hive远程服务配置和Hive远程服务调用的基础上,通过在IDEA中编写程序实现广电大案例的5个数据表创建和数据装载的代码封装。 本任务将介绍如何在IDEA开发环境中调试程序,通过程序调用的方式,将广电数据存储至Hive。

创建开发项目

打开编程软件IDEA,选择“File”→“New”,创建项目ZJSM,并将该项目放置在本地目录(如“D:\Hive\ZJSM”)。创建的具体操作可参考上小节中的内容,ZJSM项目视图如下图。 在项目的pom.xml文件中添加Hive相关依赖,操作参照上小节中的内容。

图片18

创建HiveHelper类和连接Hive

在src/main/java目录下创建新的Java类HiveHelper,用于进行数据库相关操作。 在HiveHelper类中创建一个新方法getConn(),用于通过使用JDBC连接Hive数据库。

import java.sql. *;
import java.util.ArrayList;
import java.util.List;
public class HiveHelper {
    private static String driverName="org.apache.hive.jdbc.HiveDriver";
    private static String url="jdbc:hive2://master:10000/DEFAULT";
    private Connection conn=null;
    private static String username="root";
    private static String password="123456";
    private Statement stmt=null;
    private ResultSet rs=null;
    /**
     * 获取连接
     */
    public Connection getConn() throws ClassNotFoundException, SQLException {  //使用异常处理或抛出异常
        if (null==conn)
        {
            Class.forName(driverName);
            conn=DriverManager.getConnection(url,username,password);
        }
        return conn;
    }
    /**
     * 关闭连接
     */
    public void close() {
        try {
            if (null != conn && !conn.isClosed())
                conn.close();
        } catch(SQLException e){
            e.printStackTrace();
        }finally {
            conn=null;
        }
}
//......(其他数据库操作)
}
由于在连接过程中可能出现驱动无法加载或访问数据错误等异常,故此处使用异常处理或抛出异常。

创建测试类

在src/test/java目录下创建新的测试类HiveTest,用于调用HiveHelper类,完成相关的数据库操作。

public class HiveTest {
    public static void main(String[] args) {
        String dbName="ZJSM2";
        String localFile2="/opt/data/mediamatch_userevent.csv";
        String tbName2 = "mediamatch_userevent";
        HiveHelper helper=new HiveHelper();
        //1.创建广电用户数据库
        helper.createDatabase(dbName);
        //2.1 创建用户基本数据表
        helper.createTable1(dbName);
        //2.2 创建用户状态变更数据表
        helper.createTable2(dbName);
        //2.3 创建账单数据表
        helper.createTable3(dbName);
        //2.4 创建订单数据表
        helper.createTable4(dbName);
        //2.5 创建用户收视行为数据表
        helper.createTable5(dbName);
        //3 加载CSV数据至用户状态变更数据表
        helper.loadData(localFile2,tbName2);
        //4 显示表内容
        helper.selectAll(tbName2);
    }
}

创建Hive数据库

在HiveHelper类中创建一个新方法createDatabase(String dbName),用于创建系统数据库,需要使用异常处理。

/**
     * 创建数据库
     */
    public void createDatabase(String dbName){
        try {
            stmt=getConn().createStatement();
            stmt.execute("CREATE DATABASE IF NOT EXISTS "+dbName);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

创建Hive表

在HiveHelper类中创建一个新方法createTable2(String dbName),用于创建系统数据库,需要使用异常处理。

    public void createTable1(String dbName){
        try {
            stmt=getConn().createStatement();
            stmt.execute("USE "+dbName);
            String sql;
            sql = "CREATE TABLE IF NOT EXISTS mediamatch_userevent(\n" +
                    "phone_no STRING,\n" +
                    "run_name STRING,\n" +
                    "run_time STRING,\n" +
                    "owner_name STRING,\n" +
                    "owner_code STRING,\n" +
                    "open_time STRING)\n" +
                    "ROW FORMAT DELIMITED FIELDS TERMINATED BY ';'";
            stmt.execute(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
由于数据表较多,仅以其中一份表,即用户状态变更数据表mediamatch_userevent的创建为例。 其他表的创建,读者可参照案例自行补充完成。

装载数据

在HiveHelper类中创建一个新方法loadData(String localFile,String tbName),用于从Linux本地CSV文件装载数据至Hive表,

    public void loadData(String localFile,String tbName){
        String sql= " LOAD DATA LOCAL INPATH '"+ localFile +"' OVERWRITE INTO TABLE "+tbName;
        System.out.print(sql);
        try {
            stmt=getConn().createStatement();
            stmt.execute(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
同样地,需要使用异常处理。

程序运行与调试

在菜单栏中选择“Run”→“Run 'HiveTest'”运行测试类,如下图。

图片19

如果程序运行错误,那么可依据错误提示的行号,在打开HiveTest代码后,找到相应的代码行。 单击行号右边空白处,在相应的代码前面设置断点(断点是指行号后面生成的小红点,当程序执行到断点时,系统会自动暂停,读者可以去观察程序运行的状态和相关变量的值,当需要程序继续运行时,可按F7键继续运行程序),进行程序调试,在程序调试模式下,程序遇到断点会自动中断运行。

程序调试如下图。

图片20

在菜单栏中选择“Run”→“Debug”(或按快捷键Shift+F9),可进入程序调试模式,如下图。

图片21

程序在中断情况下,可通过切换到“Debugger”窗口,从而查看变量值,查找程序是否存在拼写错误或逻辑错误,如下图。

图片22

任务描述

本任务以第4~7章的内容为基础,将广电大数据查询与处理的主要实现过程进行整理,最后封装成一个完整的程序。 由于篇幅所限,此处具体实现时仅选取几个关键环节的代码进行解析,并不展示全部封装好的代码。 本任务在IDEA中编程实现从Hive表中查询用户状态变更数据表的数据,并对用户基本数据表、用户收视行为数据表、账单数据表中的一些无效数据进行清理操作。

查询数据

在HiveHelper类中创建一个新方法selectAll(String tbName),用于查询用户状态变更数据表中的数据,由于用户状态变更数据表中的数据字段较多,因此仅以查询表中的一些数据字段为例。

    public void selectAll(String tbName){
        String sql="SELECT * FROM "+tbName;
        if (tbName.equals("mediamatch_userevent")) {
            try {
                stmt = getConn().createStatement();
                rs = stmt.executeQuery(sql);
                while (rs.next()) {
                    System.out.println(
                            rs.getString("phone_no") + "\t" +
                                    rs.getString("run_name") + "\t" +
                                    rs.getString("run_time") + "\t" +
                                    rs.getString("owner_name") + "\t" +
                                    rs.getString("owner_code") + "\t" +
                                    rs.getString("open_time")
                    );
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
在HiveTest类中调用selectAll()方法,并使用该方法查询表mediamatch_userevent中的数据,程序运行结果如下图。

图片23

删除无效用户数据

根据任务7.1,本小节将通过程序的方式,实现无效用户数据的删除。下面以用户基本数据表为例,实现无效用户数据的删除如下。 创建一个mediamatch_usermsg_clean表,将无效的数据删除,将有效的数据导入mediamatch_usermsg_clean表中。 在HiveTest类中调用cleanTable1()方法,并使用该方法删除mediamatch_usermsg表中的无效数据。运行HiveTest程序后,即可在Hive CLI使用SELECT语句查看mediamatch_usermsg_clean表中的前5行数据,如下图。

    public void cleanTable1(String dbName){
        try {
            stmt=getConn().createStatement();
            stmt.execute("USE "+dbName);
            String sql;
            sql = "CREATE TABLE IF NOT EXISTS mediamatch_usermsg_clean\n"+
                   "AS   \n"+
                   "SELECT * FROM mediamatch_usermsg \n "+
                   "WHERE \n "+ 
                   "owner_code NOT IN ('2','9','10')  \n "+
                   "AND  \n"+
                   "owner_name NOT IN ('EA级','EB级','EC级','ED级','EE级') \n "+
                   "AND \n "+
                   "sm_name IN ('数字电视','互动电视','珠江宽频','甜果电视') \n "+
                   "AND  \n"+
                   "run_name IN ('正常','欠费暂停','主动暂停','主动销户')";
            stmt.execute(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

图片24

根据任务7.1,本小节将通过程序的方式,实现无效用户数据的删除。下面以用户基本数据表为例,实现无效用户数据的删除如下。 创建一个mediamatch_usermsg_clean表,将无效的数据删除,将有效的数据导入mediamatch_usermsg_clean表中。 在HiveTest类中调用cleanTable1()方法,并使用该方法删除mediamatch_usermsg表中的无效数据。

删除无效收视行为数据

运行HiveTest程序后,即可在Hive CLI查看media_index_clean表中的前5行数据,如下图。

public void cleanTable2(String dbName){
        try {
            stmt=getConn().createStatement();
            stmt.execute("USE "+dbName);
            String sql;
            sql = "CREATE TABLE IF NOT EXISTS media_index_clean \n"+
                   "AS   \n"+
                   "SELECT * FROM media_index \n "+
                   "WHERE \n "+ 
                   "(CAST(duration AS double)/1000 >= 20  \n "+
                   "AND  \n"+
                   "CAST(duration AS double)/(1000*60*60) < 5 \n "+
                   "AND \n "+
                   "res_type='0' \n "+
                   "AND  \n"+
                   "origin_time NOT LIKE '%00'  \n"+
                   "AND  \n"+
                   "end_time NOT LIKE '%00') \n"+
                   "OR \n"+
                   "(CAST(duration AS double)/1000 >= 20 \n"+
                   "AND  \n"+
                   "CAST(duration AS double)/(1000*60*60) < 5 \n"+
                   "AND  \n"+
                   "res_type='1')  ";
            stmt.execute(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
}

图片25

删除无效账单和无效订单数据

本小节将通过程序的方式删除无效账单和无效订单数据。 根据任务7.3的无效订单数据探索,发现用户订单数据表中不存在无效订单数据,所以本小节只实现无效账单数据的删除操作。 首先创建新表(mmconsume_billevents_clean),然后删除账单数据表中的无效账单数据,最后将删除后的数据导入表中。 在HiveTest类中调用cleanTable3()方法,并使用该方法删除mmconsume_billevents表中的无效账单数据。

public void cleanTable3(String dbName){
        try {
            stmt=getConn().createStatement();
            stmt.execute("USE "+dbName);
            String sql;
            sql = "CREATE TABLE IF NOT EXISTS mmconsume_billevents_clean \n"+
                   "AS   \n"+
                   "SELECT * FROM mmconsume_billevents \n "+
                   "WHERE should_pay >= 0  ";
            stmt.execute(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
}

运行HiveTest程序后,即可在Hive CLI查看mmconsume_billevents_clean表中的前5行数据,如下图。

图片26

小结

本章首先配置和启动了Hive远程服务,以此为基础。 接着搭建了Hive远程开发环境以及通过JDBC接口实现了IDEA访问Hive数据。 最后使用程序的方式实现了广电数据的存储,并对广电数据进行了查询与处理的操作,实现第2~7章的代码封装,以利于后续广电大数据用户画像的构建、模型的应用。 其中广电大数据用户画像的构建、模型的应用,读者可自行学习实现。