Java实现Hive UDF详细步骤 (Hive 3.x版本,IDEA开发)

前言

老版本编写UDF时,需要继承 org.apache.hadoop.hive.ql.exec.UDF类,然后直接实现evaluate()方法即可。
由于公司hive版本比较高(3.x),这次编写UDF就采用了新的版本,继承类org.apache.hadoop.hive.ql.udf.generic.GenericUDF,实现三个方法

1. 新建项目

打开IDEA,新建一个项目,基本配置如下,Archetype选择图中所示
在这里插入图片描述

2.配置maven依赖

导入编写UDF需要用到的依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
    <dependency>
      <groupId>org.apache.hive</groupId>
      <artifactId>hive-exec</artifactId>
      <version>3.1.2</version>
      <exclusions>
        <exclusion>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-compress</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>8</source>
          <target>8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

3.编写代码

目录结构可自行定义,这块不影响实际功能,代码整体框架如下
我这里代码传入三列数据,返回一列数据,入参可以判断一下是否传入数据正确,以及数据类型是否匹配
主要实现三个方法,具体内容在代码块中有说明

  1. initialize
  2. evaluate
  3. getDisplayString
public class ComputeUnitPrice extends GenericUDF {
 WritableHiveDecimalObjectInspector  decimalObjectInspector;

    //初始化方法,做一些检查
    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        // 判断输入参数的个数
        if(arguments.length !=3){
            throw new UDFArgumentLengthException("This UDF Only takes 3 arguments: String, String, Decimal");
        }
        ObjectInspector param1 = arguments[0];
        ObjectInspector param2 = arguments[1];
        ObjectInspector param3 = arguments[2];
        // 判断输入参数的类型
        if(!(param1 instanceof StringObjectInspector)){
            throw new UDFArgumentException("Param1 Type is error,Must be : String");
        }
        if(!(param2 instanceof StringObjectInspector)){
            throw new UDFArgumentException("Param2 Type is error,Must be : String");
        }
//        if(!(param3 instanceof JavaConstantHiveDecimalObjectInspector)){
//            throw new UDFArgumentException("Param3 Type is error,Must be : JavaHiveDecimal");
//        }
        this.decimalObjectInspector = (WritableHiveDecimalObjectInspector ) param3;
        //函数返回值为 Decimal,需要返回 Decimal类型的鉴别器对象
        return PrimitiveObjectInspectorFactory.javaHiveDecimalObjectInspector;
    }
}

    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
        //计算逻辑编写
    }

	//udf的说明
	@Override
    public String getDisplayString(String[] children) {
        return "ComputeUnitPrice";
    }


    //main方法测试一下数据结果
	public static void main(String[] args) throws HiveException {
        ComputeUnitPrice computeUnitPrice = new ComputeUnitPrice();

        DeferredObject[] param = {new DeferredJavaObject("箱"), new DeferredJavaObject("800g*8袋/箱"), new DeferredJavaObject(100.20)};
        JavaDoubleObjectInspector javaDoubleObjectInspector = PrimitiveObjectInspectorFactory.javaDoubleObjectInspector;

        ObjectInspector stringOi = PrimitiveObjectInspectorFactory.javaStringObjectInspector;
        ObjectInspector doubleOi = PrimitiveObjectInspectorFactory.javaDoubleObjectInspector;
        computeUnitPrice.initialize(new ObjectInspector[]{stringOi, stringOi,doubleOi});
        double res =  javaDoubleObjectInspector.get(computeUnitPrice.evaluate(param));
        System.out.println("res " + res);
       
    }

4.打jar包

将项目打成jar包

mvn clean package

执行完成,target目录下寻找自己的jar包

5.上传服务器

本地上传到机器,再由机器上传到hdfs或者s3等

6.代码中引用

add jars xxxxx/compute_sku_unit_price.jar;
create temporary function compute_sku_unit_price as 'xx.xxx.xxx.xxx.ComputeUnitPrice';
${your_sql};
对于第一个问题,你可以按照以下步骤来完成: 1. 打开 IDEA,创建一个新的 Java 项目。 2. 在项目中创建一个名为 "resources" 的文件夹,并将 "nev.sql" 文件放入其中。 3. 在项目中引入 mysql-connector-java 依赖包,用来连接 MySQL 数据库。 4. 在项目中编写 Java 代码,连接到 MySQL 数据库,并执行 "nev.sql" 中的建表语句。 5. 根据建表语句,在 MySQL 数据库中创建对应的两张表。 以下是 Java 代码示例: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class Main { public static void main(String[] args) throws Exception { // 连接到 MySQL 数据库 String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(url, user, password); // 执行建表语句 Statement stmt = conn.createStatement(); String sql = "CREATE TABLE IF NOT EXISTS table1 (" + "id INT PRIMARY KEY," + "name VARCHAR(20) NOT NULL," + "age INT NOT NULL" + ")"; stmt.executeUpdate(sql); sql = "CREATE TABLE IF NOT EXISTS table2 (" + "id INT PRIMARY KEY," + "gender VARCHAR(10) NOT NULL," + "salary INT NOT NULL" + ")"; stmt.executeUpdate(sql); // 关闭连接 stmt.close(); conn.close(); } } ``` 对于第二个问题,你可以按照以下步骤来完成: 1.Hive 中创建对应的两张表,与 MySQL 数据库中的表结构相同。 2. 使用 Sqoop 工具将 MySQL 数据库中的数据导入 Hive 数据库中。 3.Hive 中查询数据,选择需要插入到另一个表中的部分数据。 4. 使用 INSERT INTO 语句将选中的数据插入到另一个表中。 以下是 Hive 命令示例: ```sql -- 创建表 CREATE TABLE IF NOT EXISTS table1 ( id INT, name STRING, age INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY &#39;\t&#39; STORED AS TEXTFILE; CREATE TABLE IF NOT EXISTS table2 ( id INT, gender STRING, salary INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY &#39;\t&#39; STORED AS TEXTFILE; -- 使用 Sqoop 导入数据 sqoop import \ --connect jdbc:mysql://localhost:3306/test \ --username root \ --password 123456 \ --table table1 \ --hive-import \ --hive-table table1 \ --create-hive-table \ --fields-terminated-by &#39;\t&#39; -- 查询数据并插入到另一个表中 INSERT INTO table2 SELECT id, gender, salary FROM table1 WHERE age > 30; ``` 对于第三个问题,你可以按照以下步骤来完成: 1.Hive 中创建一个自定义函数。 2. 编写 Java 代码实现该函数。 3. 将编写好的 Java 代码打包成 jar 包。 4.Hive 中注册 jar 包,并使用自定义函数。 以下是 Java 代码示例: ```java import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public class MyUDF extends UDF { public Text evaluate(Text str) { if (str == null) { return null; } String result = str.toString().replaceAll("_", ""); return new Text(result); } } ``` 以下是 Hive 命令示例: ```sql -- 创建函数 CREATE FUNCTION my_udf AS &#39;com.example.MyUDF&#39; USING JAR &#39;my_udf.jar&#39;; -- 使用函数 SELECT my_udf(name) FROM table1; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值