# 在Spark SQL作业中使用UDF
#### 操作场景
AI DataLake支持用户使用Hive UDF（User Defined Function，用户定义函数）进行数据查询等操作，UDF只对单行数据产生作用，适用于一进一出的场景。
#### 约束限制
自定义函数中引用static类或接口时，必须要加上"try catch"异常捕获，否则可能会造成包冲突，导致函数功能异常。
#### 环境准备
在进行UDF开发前，请准备以下开发环境。
表1UDF开发环境 
| 准备项                 | 说明                                            |
|:---|:---|
| 操作系统              | Windows系统，支持Windows7以上版本。                    |
| 安装JDK               | JDK使用21及以上版本。                                 |
| 安装和配置IntelliJ IDEA | IntelliJ IDEA为进行应用开发的工具，版本要求使用2019.1或其他兼容版本。 |
| 安装Maven           | 开发环境的基本配置。用于项目管理，贯穿软件开发生命周期。                 |
   
#### 开发流程
UDF函数开发流程参考如下：
图1UDF开发流程   
![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002671267128.png "点击放大")
表2开发流程说明 
| 序号  | 阶段                | 操作界面                 | 说明                                                                                                                  |
|:---|:---|:---|:---|
| 1 | 新建Maven工程，配置pom文件 | IntelliJ IDEA    | 参考[操作步骤]说明，编写UDF函数代码。 |
| 2  | 编写UDF函数代码           | IntelliJ IDEA    | 参考[操作步骤]说明，编写UDF函数代码。 |
| 3 | 调试，编译代码并导出Jar包   | IntelliJ IDEA    | 参考[操作步骤]说明，编写UDF函数代码。 |
| 4   | 上传Jar包到OBS        | OBS控制台             | 将生成的UDF函数Jar包文件上传到OBS目录下。                                                                                           |
| 5  | 创建UDF函数          | DataArts Studio控制台 | 在DataArts Studio控制台的"脚本开发"界面，创建UDF函数。                                                                               |
| 6  | 验证和使用UDF函数       | DataArts Studio控制台  | 在DataArts Studio控制台的"脚本开发"界面，Spark SQL作业中使用创建的UDF函数。                                                               |
   
 #### 操作步骤
1. 新建Maven工程，配置pom文件。以下通过IntelliJ IDEA 2020.2工具操作演示。
   1. 打开IntelliJ IDEA，选择"File \> New \> Project"。
      图2新建Project   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701306777.png "点击放大") 
   
   2. 选择Maven，Project SDK选择1.8，单击"Next"。
      图3选择Maven   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701306775.png "点击放大") 
   
   3. 定义样例工程名和配置样例工程存储路径，单击"Finish"完成工程创建。
      图4创建工程   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002671267132.png "点击放大") 
   
   4. 在pom.xml文件中添加如下配置。
      ```
      <dependencies>
              <dependency>
                  <groupId>org.apache.hive</groupId>
                  <artifactId>hive-exec</artifactId>
                  <version>1.2.1</version>
              </dependency>
      </dependencies>
      ```
      图5pom文件添加配置   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701186697.png "点击放大")
      
      
   
   5. 在工程路径的"src \> main \> java"文件夹上鼠标右键，选择"New \> Package"，新建Package和类文件。
      图6新建Package和类文件   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701306779.png "点击放大")
      Package根据需要定义，本示例定义为："com.huawei.demo"，完成后回车。
      图7自定义Package   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002671267130.png "点击放大")
      在包路径下新建Java Class文件，本示例定义为：SumUdfDemo。
      图8新建Java Class文件   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002671426972.png "点击放大") 
    
2. 编写UDF函数代码。UDF函数实现，主要注意以下几点：
   1. 自定义UDF需要继承org.apache.hadoop.hive.ql.exec.UDF。
   
   2. 需要实现evaluate函数，evaluate函数支持重载。
   
   
   详细UDF函数实现，可以参考如下样例代码：
   ```
   package com.huawei.demo;
   import org.apache.hadoop.hive.ql.exec.UDF;
     public class SumUdfDemo extends UDF {
       public int evaluate(int a, int b) {
        return a + b;
     }
    }
   ```
   
3. 编写调试完成代码后，通过IntelliJ IDEA工具编译代码并导出Jar包。
   1. 单击工具右侧的"Maven"，参考下图分别单击"clean"、"compile"对代码进行编译。 编译成功后，单击"package"对代码进行打包。
      图9编译打包   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701186699.png "点击放大")
      打包成功后，生成的Jar包会放到target目录下，以备后用。本示例将会生成到："D:\\AIDataLakeTest\\MyUDF\\target"下名为"MyUDF-1.0-SNAPSHOT.jar"。
      图10生成Jar包   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701186693.png "点击放大") 
    
4. 登录OBS控制台，将生成的Jar包文件上传到OBS路径下。
   ![](https://support.huaweicloud.com/devg-aidatalake/public_sys-resources/note_3.0-zh-cn.png)
   Jar包文件上传的OBS桶所在的区域需与AI DataLake的工作空间区域相同，不可跨区域执行操作。
   
5. 创建UDF函数。
   1. 在[AI DataLake管理控制台](https://console.huaweicloud.com/fabric/)左下角，单击"DataArts Studio"。
   
   2. 在"脚本开发"页面，新建Serverless Spark SQL脚本后，选择端点，Catalog和数据库。
      图11新建Serverless Spark SQL脚本   
      ![](https://support.huaweicloud.com/devg-aidatalake/zh-cn_image_0000002701306769.png) 
   
   3. 在SQL编辑区域，输入创建UDF函数的命令。
      ```
      CREATE FUNCTION TestSumUDF AS 'com.huawei.demo.SumUdfDemo' using jar 'obs://aidatalake-test-obs01/MyUDF-1.0-SNAPSHOT.jar';
      ```
      
   
   4. 单击"运行"。
    
6. 使用UDF函数。 在查询语句中使用[5]中创建的UDF函数:
   ```
   SELECT TestSumUDF(1,2);
   ```
   
7. （可选）删除UDF函数。 如果不再使用UDF函数，可执行以下语句删除该函数:
   ```
   DROP FUNCTION TestSumUDF;
   ```
   
 
