2011-07-21 88 views
5

Spring語言是否支持IN運算符?類似於SQL IN子句。Spring語言是否支持IN運算符?

public class Security { 
private secTyp1; 
public Security (String aSecTyp1) { 
    secTyp1 = aSecTyp1; 
} 
} 

Security security = new Security("BOND"); 
StandardEvaluationContext context = new StandardEvaluationContext(security); 
ExpressionParser parser = new SpelExpressionParser(); 
// This should return true 
boolean result = parser.parseExpression("secTyp1 **IN** {'BOND','SWPI'}").getValue(context, Boolean.class); 
// This should return false 
result = parser.parseExpression("secTyp1 **IN** {'FUT','SWPI'}").getValue(context, Boolean.class); 

我得到下面的異常

org.springframework.expression.spel.SpelParseException: EL1041E:(pos 8): After parsing a valid expression, there is still more data in the expression: 'IN' 
    at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:118) 
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:56) 
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:1) 
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:66) 
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:56) 
    at com.rules.AssignableSecurityRule.evaluateInCondition(AssignableSecurityRule.java:48) 
    at com.rules.AssignableSecurityRuleTest.testINCondition(AssignableSecurityRuleTest.java:43) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

回答

5

它不支持IN操作符,因爲你不需要它。您可以改爲使用方法調用功能。

因此,在列表中調用.contains(..)將執行您想要的操作。

你可以嘗試這兩種解決方案

@Test 
    public void solutionOneTest() { 
     final Security security = new Security("BOND"); 
     final EvaluationContext context = new StandardEvaluationContext(security); 

     Boolean contains = PARSER.parseExpression("{'BOND','SWPI'}.contains(#root.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertTrue(contains); 

     contains = PARSER.parseExpression("{'FUT','SWPI'}.contains(#root.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertFalse(contains); 
    } 

    @Test 
    public void solutionTwoTest() { 
     final Security security = new Security("BOND"); 
     final EvaluationContext context = new StandardEvaluationContext(); 
     context.setVariable("sec", security); 

     Boolean contains = PARSER.parseExpression("{'BOND','SWPI'}.contains(#sec.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertTrue(contains); 

     contains = PARSER.parseExpression("{'FUT','SWPI'}.contains(#sec.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertFalse(contains); 
    } 
+1

。載有()的工作原理。你也可以使用匹配:secTyp1匹配'BOND | SWPI' – Heathen

+0

@Heathen ingenius –

0

除了調用方法直接在micfra的答案,規劃環境地政司還支持一些非常強大的收集過濾表達式爲好。 Collection Selection可以過濾出匹配值,當你可以再測試大小的子表:

!{'BOND','SWPI'}.?[#this == 'BOND'].empty 

在哪裏,這是非常方便的是複雜對象的過濾列表:

!securities.?[secTyp1 == 'BOND'].empty