[Java]SQL構文ツリーを手動で構築し(sql単純ネストなし)対応するSQL文の2つを出力

13147 ワード

Entryエントリmainでsql構文ツリーを上から下へ手動で作成
package com.hy;

//   SQL   
public class Entry {
    public static void main(String[] args) throws Exception {
        
        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("level"));
        levelCompare.addChild(new ValueNode("9"));
        condistions.addChild(levelCompare);
        
        Node likeCompare=new CompareNode(" like ");
        likeCompare.addChild(new ValueNode("name"));
        likeCompare.addChild(new ValueNode("' %'"));
        condistions.addChild(likeCompare);
        
        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.getSql());
    }
}

まず出力を見せてください.
Select name,ismale From userinfo Where age>=41 and level<9 and name like ' %' order by sn asc,level desc

ノードの書き方を見てみましょう.
Nodeクラス:
package com.hy;

import java.util.ArrayList;
import java.util.List;

//
public abstract class Node {
    //        
    protected List children;
    
    //         
    protected String text="";
    
    public Node() {
        children=new ArrayList();
    }
    
    //        
    public Node addChild(Node n) {
        children.add(n);
        
        return this;
    }
    
    //      sql      
    public String getSql() throws Exception{
        String retval=this.text+"";
        
        for(int i=0;i) {
            Node child=children.get(i);
            retval+=child.getSql();
        }
        
        return retval;
    }
}

KeywordNodeクラス:
package com.hy;

//      ,      SQL select,from,where,order by       
//            
public class KeywordNode extends Node {

    public KeywordNode(String keyword) {
        this.text=keyword;
    }
}

ValueNodeクラス:
package com.hy;

//    ,        , ,  ,     
//                       
public class ValueNode extends Node {

    public ValueNode(String value) {
        this.text=value;
    }
}

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 getSql() throws Exception{
        String retval=this.text+"";
        
        List ls=new ArrayList();
        for(int i=0;i) {
            Node child=children.get(i);
            ls.add(child.getSql());    
        }
        
        retval+=String.join(seperator, ls);
        
        return retval;
    }
}

CompareNodeクラス:
package com.hy;

//     ,           , age>41,level>9
//
public class CompareNode extends Node {

    public CompareNode(String value) {
        this.text=value;
    }
    
    public String getSql() throws Exception{
        Node left=getLeftChild();
        Node right=getRightChild();
        
        String retval=left.getSql()+this.text+right.getSql()+"";
        
        return retval;
    }
    
    private Node getLeftChild() throws Exception {
        try {
            return children.get(0);
        }catch(Exception e) {
            throw new Exception("No found left node under node'"+this.text+"' ");
        }
    }
    
    private Node getRightChild() throws Exception {
        try {
            return children.get(1);
        }catch(Exception e) {
            throw new Exception("No found Right node under node'"+this.text+"' ");
        }
    }
}

前作に比べて異常が加わっており、構築時のエラーをある程度爆発させることができる.
--END-2019年9月6日18時46分
転載先:https://www.cnblogs.com/xiandedanteng/p/11477513.html