# 示例
strip("abca",'ab')-> 'c'
strip("abc",'ac')-> 'b'
下面的是StripUDF.class 以及相关的依赖pom文件 官方提供的https://cwiki.apache.org/confluence/display/Hive/HivePlugins
官方示例提供的指需要继承UDF类,但是这个实现无法对参数做对应的检查, 例如官方的一些udf方法也是这样实现 例如 regex_replace 它也是继承自udf,同样的没做参数检查,https://github.com/apache/hive/blob/master/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFRegExpReplace.java 我们下面的示例,使用继承GenericUDF 可以帮助我们完成更多的检查,但是这个实现难度要大于我们的继承udf的方法.
// StripUDF.class 代码
package com.sptk.udf;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDFUtils;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorConverter.TextConverter;
import org.apache.hadoop.io.Text;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Description(name = "strip", value = "_FUNC_(str1,str2) - 删除左右两侧指定的字符", extended = "Example:\n" + " > SELECT _FUNC_('abca','a') FROM src LIMIT 1;\n" + " bc")
public class StripUDF extends GenericUDF {
private PrimitiveObjectInspector inputOI;
private transient TextConverter stringToTrimConverter; // 指定转换器
private transient TextConverter trimCharsConverter;
private Text result = new Text();
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
// 检查参数个数
checkArguments(arguments);
// 设置udf返回的类型
return PrimitiveObjectInspectorFactory.writableStringObjectInspector;
}
private void checkArguments(ObjectInspector[] arguments) throws UDFArgumentException {
// 参数个数检查
if (arguments.length != 2) {
throw new UDFArgumentException(getUdfName() + " requires two argument. Found :"
+ arguments.length);
}
// 这个仅仅检查是不是hive支持的基础类型
for (int i = 0; i < arguments.length; i++) {
if (arguments[i].getCategory() != ObjectInspector.Category.PRIMITIVE) {
throw new UDFArgumentTypeException(i, "Only primitive type arguments are accepted but " + arguments[i].getTypeName() + " is passed.");
}
// 具体类型检查,由于检查的2个参数都是string类型 所以我们一起写了
// 转换成具体的类型做检查
PrimitiveObjectInspector.PrimitiveCategory inputType = ((PrimitiveObjectInspector) arguments[0]).getPrimitiveCategory();
switch (inputType) {
case STRING:
case CHAR:
case VARCHAR:
case VOID:
break;
default:
throw new UDFArgumentException(getUdfName() + " takes only STRING/CHAR/VARCHAR types. Found " + inputType);
}
}
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
// 获取输入参数的值 (用官方的 推荐使用转换器处理)
// strimudf 示例 https://github.com/apache/hive/blob/master/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFBaseTrim.java#L33
String src_str = arguments[0].get().toString();
String strip_str = arguments[1].get().toString();
System.out.println(src_str + strip_str);
if (src_str == null || strip_str == null) {
return null;
}
System.out.println(String.format("^[%s]*(.+)[%s]*$", strip_str, strip_str));
Pattern com = Pattern.compile(String.format("^[%s]*(.+?)[%s]*$", strip_str, strip_str));
Matcher m = com.matcher(src_str);
if (m.find()) {
result.set(m.group(1));
return result;
} else {
return null;
}
}
@Override
public String getDisplayString(String[] children) {
return getStandardDisplayString("Strip str", children);
}
}
对应的pom.xml文件, 主要提供使用的依赖给大家参考
<?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>com.sptk</groupId>
<artifactId>hive-udf</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>3.1.2</version>
<exclusions>
<exclusion>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-common</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-serde</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
</project>
这里给大家提供一份 我自己编写的jar 用于测试 链接:https://pan.baidu.com/s/1_EJge8wZQg8TTdm_iM-XrA?pwd=gzl2 提取码:gzl2
hive-udf-strip.jar
方式一: 可以先将jar包上传到 服务器目录 再使用命令
hdfs dfs -put hive-udf-strip.jar /hive_udf
方式二: 使用我们的hadoop wen ui 进行文件上传
# 注明下面的命令是hive或者datagrip中执行的
# 创建strip方法 注意 指定包的位置: com.sptk.udf.StripUDF是你自己场景的java包的位置, 这个是我自己的包
# 后面指定jar的位置,替换成你自己的
create function strip as 'com.sptk.udf.StripUDF' using jar 'hdfs://node1:8020/hive_udf/hive-udf-strip.jar';
# 如果我们测试发现有问题,我们需要重新调整jar包,重新注册. 需要先按照下面的操作进行删除 缓存的jar包 以及 我们hdfs的jar包
# 删除函数
drop function strip;
# 查看使用的jar包
list jar; # 我这里显示 /tmp/003dd8b3-0386-48ad-a4b0-8873f023a3d5_resources/hive-udf-strip.jar
# 删除 jar包
delete jar /tmp/003dd8b3-0386-48ad-a4b0-8873f023a3d5_resources/hive-udf-strip.jar
# 最好再去我的连接hive节点删除对应的jar包 [推荐做的尤其是我们调试jar包的时候] shell终端完成
rm /tmp/003dd8b3-0386-48ad-a4b0-8873f023a3d5_resources/hive-udf-strip.jar
# 删除hdfs的jar包 可以通过web ui 删除 也可以使用shell命令行删除 `hdfs dfs -delete /hive_udf/hive-udf-strip.jar`
0