LINQ (Language Integrated Query) 是 .NET 平台的亮點特性,允許在代碼中編寫類 SQL 的查詢表達式。本文探討如何在 Java 中通過 解釋器模式 實現類 LINQ 的 from...where... 查詢語法,並提供完整的表達式解析器實現代碼。
目標語法形式:
Map row = from(ColumnsDefs).where(eq("COLUMN_NAME", key)).exe().get(0);
實現難點在於 where 子句的表達式解析,需支持:
根據經典解釋器模式,構建以下角色:
interpret(Context) 方法,所有具體表達式實現此接口EqExpression、LikeExpressionAndExpression本實現簡化為兩類元素:運算元素(終結符,如列名、值)與 運算符號(非終結符,如 =、AND、LIKE)。
package com.attilax.linq;
import java.util.Map;
public class AExpression {
public Object left;
public Object rit;
public boolean checkSuitOk(Map row) {
throw new RuntimeException("no imp in base aexp class");
}
}
package com.attilax.linq;
import java.util.Map;
public class EqExpression extends AExpression {
public EqExpression(String leftCol, Object ritVal) {
this.left = leftCol;
this.rit = ritVal;
}
@Override
public boolean checkSuitOk(Map row) {
return row.get(this.left.toString()).toString().equals(this.rit.toString());
}
}
package com.attilax.linq;
import java.util.Map;
public class LikeExpression extends AExpression {
public LikeExpression(String col, String val) {
this.left = col;
this.rit = val;
}
@Override
public boolean checkSuitOk(Map row) {
return row.get(this.left.toString()).toString().contains(this.rit.toString());
}
}
package com.attilax.linq;
import java.util.Map;
public class AndExpression extends AExpression {
public AndExpression(AExpression leftExp, AExpression rightExp) {
this.left = leftExp;
this.rit = rightExp;
}
@Override
public boolean checkSuitOk(Map row) {
AExpression lft = (AExpression) this.left;
AExpression rit = (AExpression) this.rit;
return lft.checkSuitOk(row) && rit.checkSuitOk(row);
}
}

OrExpression、NotExpression、InExpression、BetweenExpression 等非終結符"age > 18 AND name LIKE 'John%'" 轉為表達式樹checkSuitOk 方法簽名,引入泛型上下文對象通過解釋器模式,我們在 Java 中構建了可擴展的類 LINQ 查詢引擎核心。此架構清晰分離語法規則與業務邏輯,便於後續擴展複雜查詢功能。