利用jsqlparser解析SQL语句

来源:互联网 发布:万户网络官网 编辑:程序博客网 时间:2024/06/09 23:55

时常会遇到很多情况,我们需要对SQL语句进行替换或者拼接。以往我们可能会用StringBuild来进行拼接。

StringBuilder sql = new StringBuilder();sql.append("select * from");sql.append(schema);sql.append(".");sql.append(table);sql.append("where id = '"+id+"'");

但是这样的操作不仅看起来不优雅,也不简洁。面对复杂的sql,有很多子循环的情况下,并不适用。

因此我们需要借助一些工具来实现这个功能。这里我们使用jsqlparser这个sql解析工具。

SqlParser - github地址:https://github.com/JSQLParser/JSqlParser

SqlParser最新版jar下载:http://search.maven.org/remotecontent?filepath=com/github/jsqlparser/jsqlparser/0.9.1/jsqlparser-0.9.1.jar

maven依赖为

        <dependency>            <groupId>com.github.jsqlparser</groupId>            <artifactId>jsqlparser</artifactId>        </dependency>

在GitHub中有很详细的介绍,我们对常用的CRUD方法做一个总结。

首先建立一个DBSelectDeParser继承SelectDeParser

public class DBSelectDeParser extends SelectDeParser {    public DBSelectDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer){        super(expressionVisitor, buffer);    }    @Override    public void visit(Table tableName) {        String schema = tableName.getSchemaName();        String table = tableName.getName();        if (fullTableName ==null){            throw new SqlvpException("table is null");        }        tableName.setSchemaName("user");        tableName.setName("age");        StringBuilder buffer = getBuffer();        buffer.append(tableName.getFullyQualifiedName());        Pivot pivot = tableName.getPivot();        if (pivot != null) {            pivot.accept(this);        }        Alias alias = tableName.getAlias();        if (alias != null) {            buffer.append(alias);        }    }}

现在来定义一个接口,每次只要调用这个接口就可以了

public interface TablePicker {    /**     * 从sql文中挑选出所有的库表     *     * @param sql sql文     * @param mode 错误的策略模式     * @param params     * @return 库表列表     */    String pickTable(String sql, ErrorMode mode, Map<String, Object> params);}

实现类:TablePickerImpl

public class TablePickerImpl implements TablePicker {    private static Logger logger = LoggerFactory.getLogger(TablePickerImpl.class);     @Override    public String pickTable(String sql, ErrorMode mode, Map<String, Object> params) {        CCJSqlParserManager parser = new CCJSqlParserManager();        StringBuilder buffer = new StringBuilder();        try {            Statement stmt = parser.parse(new StringReader(sql));            // 查询语句处理            if (stmt instanceof Select) {                Select Statement = (Select) stmt;                logger.debug("解析sql的语句: {} ",Statement.toString());                //Start of value modification                ExpressionDeParser expressionDeParser = new ExpressionDeParser();                SelectDeParser deparser = new DBSelectDeParser(expressionDeParser, buffer, mode, params);                expressionDeParser.setSelectVisitor(deparser);                expressionDeParser.setBuffer(buffer);                Statement.getSelectBody().accept(deparser);                logger.debug("替换成功,文本为: {} ",buffer.toString());                return buffer.toString();            }            // 插入语句处理            if (stmt instanceof Insert) {                Insert Statement = (Insert) stmt;                logger.debug("解析sql的语句: {} ",Statement.toString());                Table t = new Table();                t.setSchemaName("user");                t.setName("age");                Statement.setTable(t);                // 获取insert语句中的查询语句,如果没有则不替换select                Select select = Statement.getSelect();                if (select != null) {                    ExpressionDeParser expressionDeParser = new ExpressionDeParser();                    SelectDeParser deparser = new DBSelectDeParser(expressionDeParser, buffer, mode, params);                    expressionDeParser.setSelectVisitor(deparser);                    expressionDeParser.setBuffer(buffer);                    select.getSelectBody().accept(deparser);                }                logger.debug("替换成功,文本为: {} ",Statement.toString());                return Statement.toString();            }        } catch (JSQLParserException e) {            logger.error(e.getMessage());        }        // 如果四种条件都不匹配则抛出异常。        throw new SqlvpException("error sql can not be parse!check your sql!");    }}

通过以上操作我们就完成了对查询和插入语句的解析替换,查询和插入是两个不同的操作,所以语句解析也不相同。

官方支持各种SQL语句,可以查看源码包。
这里写图片描述

同样还支持对where语句的解析,大家可自行测试。

原创粉丝点击