JSqlParser SQL语句解析器(学习笔记 2020.12.19)

4 篇文章 0 订阅

JSqlParser SQL语句解析器 (学习笔记 2020.12.19)

前言:

JSqlParser是一个SQL语句解析器。它将SQL转换为Java类的可遍历层次结构。JSqlParser不仅限于一个数据库,而且还支持Oracle,SqlServer,MySQL,PostgreSQL等许多特殊功能。例如,它支持使用(+)的Oracle联接语法,使用::的PostgreSQL转换语法,关系型。运算符,例如!=等。

用于安全的拼接SQL

1.0 引入依赖

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

2.0 解析与添加/修改例子:

@Test
    public void contextLoads2() throws Exception { 
        // 解析sql
        Statement statement = CCJSqlParserUtil
                .parse("select b.second_type from battery b left join  user u on u.id=b.user_id where 1=1 or 1=2 AND 2=2 order by b.ctime DESC limit ?,?");
        // 获取查询语句
        Select selectStatement = (Select) statement;
        // 获取查询身体
        PlainSelect selectBody = (PlainSelect) selectStatement.getSelectBody();
        this.getWhereANDADD(selectBody);
        this.getOrderByAndLimit(selectBody);
        this.getTableName(selectStatement,selectBody);
        this.getSelectItemsAndADD(selectStatement, selectBody);
        // 输出最终语句字符串
        System.out.println(selectStatement.toString());
        // 获取分组
        selectBody.getGroupBy();
        //获取等等省略...
    }

    /**
     * 获取where条件与添加/修改
     *
     * @param selectBody
     * @author: ZhiHao
     * @date: 2020/12/19
     */
    private void getWhereANDADD(PlainSelect selectBody) throws JSQLParserException {
        // 获取抽象where(也可以指定强转具体表达式), 没有则为null
        Expression where = selectBody.getWhere();
        // 解析where后面条件1=1 or 1=2 AND 2=2
        ExpressionDeParser expressionVisitor = new ExpressionDeParser();
        where.accept(expressionVisitor);
        StringBuilder buffer = expressionVisitor.getBuffer();
        // 添加条件表达式
        buffer.append(" AND test = 666");
        // 解析条件表达式
        where = CCJSqlParserUtil.parseCondExpression(buffer.toString());
        // 设置条件表达式
        selectBody.setWhere(where);
    }

    /**
     * 获取语句limit与order By, 修改/增加
     *
     * @param selectBody
     * @author: ZhiHao
     * @date: 2020/12/19
     */
    private void getOrderByAndLimit(PlainSelect selectBody) {
        // 获取是否有limit, 没有则为null
        Limit limit = selectBody.getLimit();
        LongValue offset = (LongValue) limit.getOffset();
        // get获取, set修改为22开始
        offset.setValue(22);
        LongValue rowCount = (LongValue) limit.getRowCount();
        // get获取, 修改为获取111条
        rowCount.setValue(111);
        // 获取排序字段, 没有则为null
        List<OrderByElement> orderByElements = selectBody.getOrderByElements();
        String name = null;
        for (OrderByElement orderByElement : orderByElements) {
            //获取字段
            Column expression = (Column) orderByElement.getExpression();
            // 获取表别名
            name = expression.getTable().getName();
            // 设置升序
            orderByElement.setAsc(true);
            // 字段名称
            System.out.println(expression.getColumnName());
        }
        OrderByElement orderByElement = new OrderByElement();
        orderByElement.setAsc(false);
        orderByElement.setExpression(new Column(name+".测试增加排序字段"));
        orderByElements.add(orderByElement);
    }

    /**
     * 获取所有表名与别名
     *
     * @param selectStatement
     * @param selectBody
     * @author: ZhiHao
     * @date: 2020/12/19
     */
    private void getTableName(Select selectStatement, PlainSelect selectBody) {
        // 获取所有表名
        TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
        List<String> tableList = tablesNamesFinder.getTableList(selectStatement);
        // 获取from后面表名与别名
        Table table = (Table) selectBody.getFromItem();
        System.out.println(table.getName());
        System.out.println(table.getAlias().getName());
        // 获取多表后面表名与别名
        List<Join> joins = selectBody.getJoins();
        for (Join join : joins) {
            Table rightItem  = (Table) join.getRightItem();
            System.out.println(rightItem.getName());
            System.out.println(rightItem.getAlias());
        }
    }

    /**
     * 获取查询返回字段并新增返回字段
     *
     * @param selectStatement
     * @param selectBody
     * @author: ZhiHao
     * @date: 2020/12/19
     */
    private void getSelectItemsAndADD(Select selectStatement, PlainSelect selectBody) {
        // 获取查询返回的字段
        List<SelectItem> selectItems = selectBody.getSelectItems();
        SelectExpressionItem item = new SelectExpressionItem();
        // 设置返回字段
        item.setExpression(new Column("b.测试添加字段"));
        // 返回字段别名
        item.setAlias(new Alias("b"));
        // 添加进查询返回字段
        selectItems.add(item);
        // 结果: SELECT b.second_type, b.测试添加字段 AS b FROM ........
    }

1

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懵懵懂懂程序员

如果节省了你的时间, 请鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值