[Java]手动构建SQL语法树(sql简单无嵌套)并输出与之对应的SQL语句之一
package com.hy; // 构建SQL语法树 public class Entry { public static void main(String[] args) { Node query=new SetNode(" "); query.addChild(new KeywordNode("Select")); Node fields=new SetNode(","); fields.addChild(new ValueNode("name")); fields.addChild(new ValueNode("ismale")); query.addChild(fields); query.addChild(new KeywordNode("From")); Node tables=new SetNode(","); tables.addChild(new ValueNode("userinfo")); query.addChild(tables); query.addChild(new KeywordNode("Where")); Node condistions=new SetNode(" and "); Node ageCompare=new CompareNode(">="); ageCompare.addChild(new ValueNode("age")); ageCompare.addChild(new ValueNode("41")); condistions.addChild(ageCompare); Node levelCompare=new CompareNode("<"); levelCompare.addChild(new ValueNode("left")); levelCompare.addChild(new ValueNode("9")); condistions.addChild(levelCompare); query.addChild(condistions); query.addChild(new KeywordNode("order by")); Node orders=new SetNode(","); orders.addChild(new ValueNode("sn asc")); orders.addChild(new ValueNode("level desc")); query.addChild(orders); System.out.println(query.toString()); } }
输出如下:
Select name,ismale From userinfo Where age>=41 and left<9 order by sn asc,level desc
看看和这张图是不是很像呢?
以下是各个节点类的代码:
Node抽象基类
package com.hy; import java.util.ArrayList; import java.util.List; // 节点抽象类,作为各种节点的基类 public abstract class Node { // 此节点的子节点 protected List<Node> children; // 表示此节点的文字 protected String text=""; public Node() { children=new ArrayList<Node>(); } // 添加一个子节点 public Node addChild(Node n) { children.add(n); return this; } public String toString() { String retval=this.text+""; for(int i=0;i<children.size();i++) { Node child=children.get(i); retval+=child.toString(); } return retval; } }
Compare类:
package com.hy; // 比较节点,用来表示条件比较的节点,如age>41,level>9 // 此类节点下面理论上存在左右两个节点,如果存在查询也可能存在多个子节点 public class CompareNode extends Node { public CompareNode(String value) { this.text=value; } public String toString() { Node left=children.get(0); Node right=children.get(1); String retval=left+this.text+right+""; return retval; } }
KeywordNode类:
package com.hy; // 关键字节点,比如用来表示SQL中select,from,where,order by等关键字的节点 // 此类节点下面没有子节点 public class KeywordNode extends Node { public KeywordNode(String keyword) { this.text=keyword; } }
SetNode类:
package com.hy; import java.util.ArrayList; import java.util.List; // 集合节点,比如用来表示SQL中字段组,表组,条件组,and组等容纳多个子节点的的节点,整条SQL也是这个节点 // 此类节点下面一般有多个子节点,如查询多个字段,从多个表查询,包含多个条件,按多种情况排序等 public class SetNode extends Node { // 子节点之间的分隔符 protected String seperator; public SetNode() { seperator=""; } public SetNode(String seperator) { this.seperator=seperator; } public String toString() { String retval=this.text+""; List<String> ls=new ArrayList<String>(); for(int i=0;i<children.size();i++) { Node child=children.get(i); ls.add(child.toString()); } retval+=String.join(seperator, ls); return retval; } }
ValueNode类:
package com.hy; // 值节点,比如用来表示字段,表,条件,数值等节点 // 此类节点下面如果存在查询也可能存在多个子节点 public class ValueNode extends Node { public ValueNode(String value) { this.text=value; } }
--END--2019年9月6日15点44分