1、需求背景
根据多个维度动态组合值获取最终复核的规则,这么说比较抽象,举个例子来说明吧,
比如现在申请信用卡,可能要考虑到一些维度来判断最终卡片的额度,有性别、年龄、学历、职业等维度。
那么最终排列组合会出现很多情况,随便列举如下:
排列组合结果
性别 | 年龄 | 学历 | 职业 | 最终额度 |
男 | <20 | 8000 | ||
男 | 20-25 | 本科 | 15000 | |
男 | 25-30 | 大专 | 30000 | |
女 | 20-25 | 本科 | 程序员 | 30000 |
女 | 25-30 | 大专 | 服务员 | 20000 |
由于维度不确定(比如再根据月薪),维度枚举值较多(学历还有硕士、博士、研究生等),因此就不再列举。
2、要求在数据库中以配置形式呈现
同样由于这个原因如果所有校验逻辑在代码写死维护起来也是响当困难(组合判断多,万一最终额度有所修改,每次都得改程序),为了以后方便维护,需求建议将最终组合配置在数据库实现,首先考虑表设置,最起码要有一个字段用来保存取了哪几个维度,一个字段保存这个维度值,一个字段保存最终额度,于是一个简单的表就出来了如下所示:
看到这个组合这个时候有个疑问了,如果根据维度选择a,b组合,同时满足id为3和4的情况下会有两条数据,这个怎么取值呢,最终根据业务判断取最低值即可,也就是根据维度查询多条数据最终取个最低值即可,但问题是这个维度条件在java程序中怎么应用呢?
3、实现java应用数据库配置代码
可以使用JexlEngine、Expression、JexlContext等类来共同实现,应用jar包为commons-jexl-2.1.1.jar,代码如下:
import java.util.HashMap;
import java.util.Map;import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;public class SqlMethodUtil {
public static Object invokeMethod(String jexlExp, Map<String, String> map) {
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression(jexlExp);
JexlContext jc = new MapContext();
for (String key : map.keySet()) {
jc.set(key, map.get(key));
}
if (null == e.evaluate(jc)) {
return "";
}
return e.evaluate(jc);
}
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("a", "A");//模拟多个维度组合,a维度值为A,b维度值为B
map.put("b", "B");
//模拟数据库配置维度条件与当前维度对比
String boolStr = DyMethodUtil.invokeMethod("a.equals('A')&&b.equals('B')", map).toString();
String boolStr1 = DyMethodUtil.invokeMethod("!a.equals('A')&&b.equals('B')", map).toString();
//输出最终结果
System.out.println("result:"+boolStr);
System.out.println("result:"+boolStr1);
}}
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;
public class SqlMethodUtil{
public static Object invokeMethod(String jexlExp, Map<String, String> map) {
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression(jexlExp);
JexlContext jc = new MapContext();
for (String key : map.keySet()) {
jc.set(key, map.get(key));
}
if (null == e.evaluate(jc)) {
return "";
}
return e.evaluate(jc);
}
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("a", "A");//模拟多个维度组合,a维度值为A,b维度值为B
map.put("b", "B");
//模拟数据库配置维度条件与当前维度对比
String boolStr = DyMethodUtil.invokeMethod("a.equals('A')&&b.equals('B')", map).toString();
String boolStr1 = DyMethodUtil.invokeMethod("!a.equals('A')&&b.equals('B')", map).toString();
//输出最终结果
System.out.println("result:"+boolStr);
System.out.println("result:"+boolStr1);
}
}
最终运行结果如下: