[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分


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM