spark开发自定义udf函数sql版全过程
1.写一个java类继承抽象类GenericUDF
package fun; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; public class LxFun extends GenericUDF { @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { return PrimitiveObjectInspectorFactory.writableHiveDecimalObjectInspector; } @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { if (arguments == null || arguments.length == 0) { return null; } if (arguments[0].get() == null || arguments[0].get() == null) { return null; } else { String lx = arguments[0].get().toString(); String qx = arguments[1].get().toString(); HiveDecimalWritable lx_dec = new HiveDecimalWritable(lx); lx_dec.mutateAdd(new HiveDecimalWritable(qx)); return lx_dec; } } @Override public String getDisplayString(String[] children) { return getStandardDisplayString("abs", children); } }
initialize方法必须返回一个evaluate方法中同样类型的ObjectInspector,evaluate是自定义函数的逻辑,
arguments参数为入参的集合通过arguments集合下表.get()方法获取数据类容
操作完成之后打成jar包上传至hdfs
然后通过datagrip或者其他图像化界面连接spark
其中 如果已经开启了thriftserver 并且 创建了自定义函数 并且使用的是之前同路径的jar包会报错:找不到方法udf/udaf/ 的方法
这是因为在thriftserver 中已经有了缓存 需要重启thriftserver 在执行
add jar hdfs://ip:8020/path/demo.jar;
create temporary function LxFun as 'fun.Demo';
--该fun.Demo为方法包名加类名
select LxFun('1.0001','2.0001') ;
--如果需要持久化该自定义函数
CREATE FUNCTION LxFun as 'fun.Demo' USING JAR 'hdfs://ip:8020/path/demo.jar' ;
运行结果
具体的使用案例请看spark官方文档与 Hive UDF/UDAF/UDTF 集成 - Spark 3.5.0 文档 (apache.org)