我必须从D/B中检索一组列值并将其作为条件进行检查。
例如,我将在 D/B 列中具有 "value > 2"
、 "4 < value < 6"
等字符串。(值是一直比较的值)。我将在我的代码中声明一个变量值,我应该评估这个条件。
int value = getValue();
if (value > 2) //(the string retrieved from the D/B)
doSomething();
我该怎么做??任何帮助都是穆切赫赞赏。谢谢。
下面是使用标准(Java 1.6+)脚本库的示例:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Test {
public static void main(String[] args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval("value = 10");
Boolean greaterThan5 = (Boolean) engine.eval("value > 5");
Boolean lessThan5 = (Boolean) engine.eval("value < 5");
System.out.println("10 > 5? " + greaterThan5); // true
System.out.println("10 < 5? " + lessThan5); // false
}
}
您基本上是在计算脚本表达式。根据该表达式中允许的内容,您可以使用非常简单(标识组的正则表达式)或非常复杂(嵌入 JavaScript 引擎?)的东西。
我假设您正在查看一个简单的情况,其中表达式为: [边界0][操作员]"值" [运算符] [边界 1]
可以省略一个(但不是两个)[边界] [运算符] 组。(如果两者都存在,则运算符应相同)
我会使用正则表达式来捕获组。
像这样:(?:(\d+)\s*([<>])\s*)?value(?:\s*([<>])\s*(\d+))?
然后: 边界 1 = 组 (1);运算符 1 = 组 (2);运算符 2 = 组 (3);边界 2 = 组 (4)
这不会是微不足道的:你需要一个解析器来解析数据库中使用的表达式语言。如果它是一些标准的,指定良好的语言,那么你也许可以在互联网上找到一个,但如果它是内部的东西,那么你可能需要编写自己的语言(也许使用像ANTLR这样的解析器生成器)。
javax.script 包包含一些用于集成外部脚本引擎(如 Javascript 解释器)的工具。另一种想法是引入一个脚本引擎并将表达式提供给它。
您应该尝试通过执行以下操作来解析 if 语句中的字符串
if(parseMyString(getValue()))
doSomething();
在parseMyString中,可以确定您需要评估的条件。如果您不知道如何创建解析器,请查看:http://www.javapractices.com/topic/TopicAction.do?Id=87
这本身并不能回答你的问题;它提供了一个可能影响相同结果的替代解决方案。
与其使用定义条件的伪代码存储单个数据库列,不如创建一个表,其中架构定义必须满足的条件类型以及这些条件的值。 这简化了这些条件的编程评估,但如果要评估各种类型的条件,则可能会变得复杂。
例如,您可能有一个如下所示的表。
CONDITION_ID | MINIMUM | MAXIMUM | IS_PRIME | ETC.
______________________________________________________
1 | 2 | NULL | NULL | ...
2 | 4 | 6 | NULL | ...
这些行条目分别映射到规则 value > 2
和 6 > value > 4
。
与您提供的方法相比,这带来了许多好处。
- 提高性能和清洁度
- 可以在数据库级别评估条件,并可用于筛选查询
- 您不必担心处理伪代码语法被破坏的场景
为了以最大的灵活性评估条件,请使用专为嵌入而设计的脚本语言,例如 MVEL 可以解析和评估简单的条件表达式,如问题中的条件表达式。
与在 Java 1.6+ 中使用脚本引擎(特别是使用 JavaScript)相比,使用 MVEL 具有一个巨大的优势:使用 MVEL,您可以将脚本编译为字节码,从而使它们的评估在运行时更加高效。
(Java 7)允许在字符串上切换大小写语句,如果没有太多可能的变体,你可以这样做或类似:
int value = getValue();
switch(myString) {
case "value > 2" : if (value > 2) { doSomething();} break;
case "4 < value < 6" : if (value > 4 && value < 6) { doSomethingElse();} break;
default : doDefault();
}
Java 7 之外,一个非常好的方法是使用枚举。声明枚举,如下所示
上面的枚举有一个常量集合,其值设置为您希望从数据库返回的字符串。由于您可以在开关情况下使用枚举,因此剩余的代码变得容易
enum MyEnum
{
val1("value < 4"),val2("4<value<6");
private String value;
private MyEnum(String value)
{
this.value = value;
}
}
public static void chooseStrategy(MyEnum enumVal)
{
int value = getValue();
switch(enumVal)
{
case val1:
if(value > 2){}
break;
case val2:
if(4 < value && value < 6) {}
break;
default:
}
}
public static void main(String[] args)
{
String str = "4<value<6";
chooseStrategy(MyEnum.valueOf(str));
}
您所要做的就是将字符串传递给 enum.valueof 方法,它将返回适当的枚举,该枚举放在开关大小写块中以执行条件操作。在上面的代码中,您可以传递任何字符串来代替此示例中传递的内容