[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

看看和这张图是不是很像呢?

select username, ismale from userinfo where age > 20 and level > 5 and 1 = 1

以下是各个节点类的代码:

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分

原文地址:https://www.cnblogs.com/heyang78/p/11475199.html