Java解析SQL的基本思路

简介: Java解析SQL的基本思路

天天在写sql,一直很好奇sql到底咋解析的,于是随便整个小demo。


比如sql是:


String sql = "select name,score,sex from users where name = 'jack' and isdelete <> 1 ; ";


中间可能有1个或者多个空格,就想着怎么着也得有个分词的类,就叫做Tokenizer吧。

public class Tokenizer implements Iterator<String> {
    String[] tokens;
    int index = 0;
    public Tokenizer(String sql) throws BadSqlGrammarException {
        sql = sql.trim();
        if (!sql.endsWith(";")) {
            throw new BadSqlGrammarException("SQL未正确结束!");
        }
        //去除多余的空格
        sql = sql.replace(";", " ;").replaceAll("\\s+", " ");
        //分词
        tokens = sql.split(" ");
    }
    @Override
    public boolean hasNext() {
        return index < tokens.length;
    }
    @Override
    public String next() {
        return tokens[index++];
    }
}


实现Iterator是因为需要去遍历维护的String数组,方便后面解析。

然后是parser类,里面聚合一个Tokenizer的引用。

public class Parser {
    Tokenizer tokenizer;
    DBCmd cmd;
    Map<String, DBCmd> cmdMap = new HashMap<>();
    public Parser(String sql) throws BadSqlGrammarException {
        //用查表法,代替一大堆的if else
        this.cmdMap.put("select", new SelectCmd());
        this.tokenizer = new Tokenizer(sql);
        //根据第一个sql关键字来确定是什么sql命令
        this.cmd = this.cmdMap.get(tokenizer.next());
        if (cmd == null)
            throw new BadSqlGrammarException("未识别的sql命令!");
    }
    public void query() throws BadSqlGrammarException {
        cmd.query(tokenizer);
    }
}


DBCmd做成一个抽象类,不同的命令需要单独设计一个类,去继承他。DBCmd就弄一些通用的方法即可。

public abstract class DBCmd {
    public abstract void query(Tokenizer tokenizer) throws BadSqlGrammarException;
    protected String splitUntilEnd(Tokenizer tokenizer) throws BadSqlGrammarException {
        return splitUntil(tokenizer, ";");
    }
    protected String splitUntil(Tokenizer tokenizer, String until) throws BadSqlGrammarException {
        StringBuffer sb = new StringBuffer();
        boolean find = false;
        while (tokenizer.hasNext()) {
            String next = tokenizer.next();
            if (!next.equals(until)) {
                sb.append(next).append(" ");
                continue;
            } else {
                find = true;
                break;
            }
        }
        if (!find)
            throw new BadSqlGrammarException("语法不正确");
        return sb.toString();
    }
}


只测试一下select语法,所以只写一个select操作类。

public class SelectCmd extends DBCmd {
    @Override
    public void query(Tokenizer tokenizer) throws BadSqlGrammarException {
        String querys = splitUntil(tokenizer, "from");
        String tableName = tokenizer.next();
        String condition = null;
        if (tokenizer.hasNext() && tokenizer.next().equals("where")) {
            condition = splitUntilEnd(tokenizer);
        }
        System.out.println("查询字段:" + querys);
        System.out.println("查询表:" + tableName);
        System.out.println("查询条件:" + condition);
    }
}


最后测试一下子:

public static void main(String[]args)throws BadSqlGrammarException{
        String sql="select  name,score,sex from    users where name = 'jack' and isdelete <> 1   ;  ";
        Parser parser=new Parser(sql);
        parser.query();
}


效果:


查询字段:name,score,sex

查询表:users

查询条件:name = 'jack' and isdelete <> 1


仔细一想,如果涉及到连表,where条件多层嵌套,甚至子查询,就GG了。实在是够复杂的。本文仅为抛砖引玉,匿了。

相关文章
|
10小时前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的深度解析
【5月更文挑战第12天】本文将深入探讨Java 8中的两个重要新特性:Lambda表达式和Stream API。我们将从基本概念入手,逐步深入到实际应用场景,帮助读者更好地理解和掌握这两个新特性,提高Java编程效率。
41 2
|
10小时前
|
XML JavaScript Java
详解Java解析XML的四种方法
详解Java解析XML的四种方法
15 1
|
10小时前
|
Java
解析java中的数组
解析java中的数组
12 3
|
10小时前
|
存储 Java 程序员
Java面向对象编程的基础概念解析
Java面向对象编程的基础概念解析
15 0
|
SQL Java 关系型数据库
V$SQLAREA解析
V$SQLAREA lists statistics on shared SQL area and contains one row per SQL string.
782 0
|
10小时前
|
SQL XML Linux
SQL Server的版本
【5月更文挑战第14天】SQL Server的版本
14 3
|
10小时前
|
SQL 存储 数据库连接
LabVIEW与SQL Server 2919 Express通讯
LabVIEW与SQL Server 2919 Express通讯
|
10小时前
|
SQL Windows
安装SQL Server 2005时出现对性能监视器计数器注册表值执行系统配置检查失败的解决办法...
安装SQL Server 2005时出现对性能监视器计数器注册表值执行系统配置检查失败的解决办法...
14 4
|
10小时前
|
SQL 数据可视化 Oracle
这篇文章教会你:从 SQL Server 移植到 DM(上)
这篇文章教会你:从 SQL Server 移植到 DM(上)
|
10小时前
|
SQL 关系型数据库 数据库
SQL Server语法基础:入门到精通
SQL Server语法基础:入门到精通
SQL Server语法基础:入门到精通

推荐镜像

更多