zoukankan      html  css  js  c++  java
  • [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分

  • 相关阅读:
    淘宝nginx的学习使用,安装及反向代理,负载均衡
    Linux5
    Linux4
    Linux权限相关及yum源的配置
    linux基本命令及python3的环境配置
    使用Guava RateLimiter限流
    Runnable与Callable 区别
    [Kafka] 如何保证消息不丢失
    [多线程] 等待所有任务执行完成
    [Docker] 快速安装mysql
  • 原文地址:https://www.cnblogs.com/heyang78/p/11477513.html
Copyright © 2011-2022 走看看