因项目需求原因,需获取中文拼音首字母大写的需求,hive 中 内置函数不满足需求,故新创建一个maven 项目,自定义udf 函数。
准备
- pom.xml
- 注意: hive 版本须和线上一致
<dependencies>
<!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j -->
<!--中文转拼音 jar 工具类-->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<!--用于编译jar ,把项目相关的jar打包进去-->
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.allen.capturewebdata.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
- 拼音工具类 代码
package com.huawei.utils;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public class PinYin4jUtils {
/**
* 将字符转换成拼音 获取首字母 大写
*
* @param hanyu
* @return String
*/
public static String getFirstPinYin(String hanyu) {
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
StringBuilder firstPinyin = new StringBuilder();
char[] hanyuArr = hanyu.trim().toCharArray();
try {
for (int i = 0, len = hanyuArr.length; i < len; i++) {
if(Character.toString(hanyuArr[i]).matches("[\\u4E00-\\u9FA5]+")){
String[] pys = PinyinHelper.toHanyuPinyinStringArray(hanyuArr[i],format);
firstPinyin.append(pys[0].charAt(0));
}else {
firstPinyin.append(hanyuArr[i]);
}
}
} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
badHanyuPinyinOutputFormatCombination.printStackTrace();
}
return firstPinyin.toString();
}
public static void main(String[] args) {
String s1 = "瓯海 我的程(A6-2a、A6-3a地块)";
String headArray = getFirstPinYin(s1); // 获得每个汉字拼音首字母
System.out.println(headArray);
}
}
- udf函数 重写evaluate方法
package com.huawei.udf;
import com.huawei.utils.PinYin4jUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
/**
* 注册udf 注:需要继承hive 中udf类
* 获取中文汉字首字母 大写
*/
public class PingYinUDF extends UDF {
public String evaluate(String input) {
if (input.isEmpty()){
return "";
}else {
return PinYin4jUtils.getFirstPinYin(input);
}
}
}
- 打包
mvn package assembly:single
会生成一个jar *******-jar-with-dependencies.jar
- 注册udf 函数
- 上传jar 到hdfs 上
- 创建 udf 函数
注: 注册函数只能在当前库中使用,即 当前是default ,则只能在 default 数据库中使用
hive> CREATE FUNCTION get_py AS 'com.huawei.udf.PingYinUDF'
USING JAR 'hdfs://hadoop001:9000/lib/*****-jar-with-dependencies.jar';
- 测试
注: 注册函数只能在当前库中使用,即 当前是ods,则使用ods.get_py()来调用
hive> select default.get_py("瓯海#!噢噢");
OK
OH#!OO
Time taken: 0.031 seconds, Fetched: 1 row(s)
hive>
- 在mysql 元数据中FUNCS表中查看 注册的udf 函数
mysql> select * from hivedb.FUNCS;
+---------+-------------------------+-------------+-------+-------------+-----------+------------+------------+
| FUNC_ID | CLASS_NAME | CREATE_TIME | DB_ID | FUNC_NAME | FUNC_TYPE | OWNER_NAME | OWNER_TYPE |
+---------+-------------------------+-------------+-------+-------------+-----------+------------+------------+
| 1 | com.huawei.udf.PingYinUDF | 1594721019 | 1 | get_pingyin | 1 | NULL | USER |
| 6 | com.huawei.udf.PingYinUDF | 1594722008 | 1 | get_py | 1 | NULL | USER |
| 11 | com.huawei.udf.PingYinUDF | 1594783353 | 6 | get_py | 1 | NULL | USER |
+---------+-------------------------+-------------+-------+-------------+-----------+------------+------------+
3 rows in set (0.00 sec)
注: 表中 DB_ID 代表着 该函数 可以在哪儿使用 如 1代表着 default
- udf 注册其他方式 : 自定义UDF函数一 注册到hive源码