Hive中给了很多系统函数,官网 给了很多函数可以参考。但是复杂的业务中,官方函数并不一定能满足特定化的需求,这时可以自定义函数来满足需求。
参考:官网中的关于UDF部分的链接
1. 在IDEA中创建一个项目,配置pom.xml 添加依赖如下: 1 2 3 4 5 <dependency > <groupId > org.apache.hive</groupId > <artifactId > hive-exec</artifactId > <version > 2.1.1</version > </dependency >
2. 创建一个类,例如创建一个把字符串全部转换为小写的UDF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package tech.mapan.hive;import org.apache.hadoop.hive.ql.exec.UDF;public class Lower extends UDF { public String evaluate (String s) { if (s == null ) { return null ; } return s.toLowerCase(); } }
3. 打jar包,把jar包放在 /opt/local/hive/lib 这一步就不在赘述,默认大家都会
4. 配置环境变量 CDH官网 写的在hive-site.xml中配置hive.aux.jars.path
,但是我配置完后并没有生效,不过官网写
The directory location is set in the environment as HIVE_AUX_JARS_PATH
and will generally override the hive.aux.jars.path
property set in XML files, even if hive.aux.jars.path
is set in an advanced configuration snippet.
意思就是环境变量的优先级要高于XML,所以建议直接配置环境变量。
在root用户下:
1 2 3 4 vim /etc/profile.d/hive.sh export HIVE_AUX_JARS_PATH=/opt/local/hive/libexport PATH=$PATH :$HIVE_AUX_JARS_PATH
执行source /etc/profile
刷新环境变量。
5. 进入hive-cli中,创建函数 1 2 3 4 5 6 7 8 9 hive (default)> create function mylower as "tech.mapan.hive.Lower" ; OK Time taken: 0.285 seconds hive (default)> select mylower("HELLO WORLD" ); OK _c0 hello world Time taken: 0.18 seconds, Fetched: 1 row(s)
这样就向系统添加了一个函数 mylower(), 退出hive-cli再次进入依然生效。
随手写了几个常用的UDF函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package tech.mapan.hive;import org.apache.hadoop.hive.ql.exec.UDF;public class BitAnd extends UDF { public String evaluate (String a, String b) { String result; if (a==null ||b==null ){ result = null ; }else { int i = Integer.parseInt(a); int j = Integer.parseInt(b); result = Integer.toString(i & j); } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package tech.mapan.hive;import org.apache.hadoop.hive.ql.exec.UDF;public class Greatest extends UDF { public String evaluate (String... strings) { int [] arr = new int [strings.length]; int i = 0 ; for (String s : strings) { if (s == null ) { return null ; } else { arr[i++] = Integer.parseInt(s); } } int max = arr[0 ]; for (int j = 1 ; j < arr.length; j++) { if (arr[j] > max) { max = arr[j]; } } return Integer.toString(max); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package tech.mapan.hive;import org.apache.hadoop.hive.ql.exec.UDF;public class MaskAddress extends UDF { public String evaluate (String s) { String result = "" ; if (s == null ) { return null ; } else if (s.length() > 15 ) { result = s.substring(0 , 14 ); } else { result = s; } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package tech.mapan.hive;import org.apache.hadoop.hive.ql.exec.UDF;public class MaskMail extends UDF { public String evaluate (String s) { String res = "" ; if (s == null ) { res = null ; } else { String[] split = s.split("@" ); res = split[0 ] + "@*****" ; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package tech.mapan.hive;import org.apache.hadoop.hive.ql.exec.UDF;public class MaskNo extends UDF { public String evaluate (String s) { String res = "" ; if (s == null ) { res = null ; } else { res = s.substring(0 , 2 ) + "****" + s.substring(s.length() - 2 ); } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package tech.mapan.hive; import org.apache.hadoop.hive.ql.exec.UDF; /** * @program: UDF * @description: 手机号码脱敏,手机号码后6位换成* * @author: MaPan * @create: 2020-03-22 13:08 **/ public class MaskPhone extends UDF { public String evaluate(String s) { String res = ""; if (s == null) { res = null; } else { res = s.substring(0, 5) + "******"; } return res; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package tech.mapan.hive;import org.apache.hadoop.hive.ql.exec.UDF;public class GenderETL extends UDF { public String evaluate (String s) { String res = "" ; if (s == null ) { res = null ; } else { if (s.equals("男" ) || s.equals("M" ) || s.equals("1" )) { res = "男" ; } else if (s.equals("女" ) || s.equals("F" ) || s.equals("0" )) { res = "女" ; } else { res = "未知" ; } } return res; } }
附:jar包下载