• [Java]手动构建SQL语法树(sql简单无嵌套)并输出与之对应的SQL语句之二


    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<Node> children;
        
        // 表示此节点的文字
        protected String text="";
        
        public Node() {
            children=new ArrayList<Node>();
        }
        
        // 添加一个子节点
        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<children.size();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<String> ls=new ArrayList<String>();
            for(int i=0;i<children.size();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分

  • 相关阅读:
    golang获取URL
    Golang读取HTML中Table数据到二维数组
    Golang的GUI开发包fyne基本教程
    C#搭建安川机器人上位机
    程序计数器
    SpringBoot定时任务详解
    mysql 5.7安装
    springboot 配置多数据源
    mysql 查询某一天数据
    java如何获取当前日期和时间
  • 原文地址:https://www.cnblogs.com/heyang78/p/11477513.html
Copyright © 2020-2023  润新知