jsqlparse使用,将等于替换为in

jsqlparse

介绍

JSqlParse是一款很精简的sql解析工具,它可以将常用的sql文本解析成具有层级结构的“语法树”,我们可以针对解析后的“树节点(也即官网里说的有层次结构的java类)”进行处理进而生成符合我们要求的sql形式。
官网给的介绍很简洁:JSqlParser 解析 SQL 语句并将其转换为 Java 类的层次结构。生成的层次结构可以使用访问者模式进行访问(官网地址:JSqlParser - Home)。
参考文献:
Sql解析转换之JSqlParse完整介绍_jsqlparser_Interest1_wyt的博客-CSDN博客

将等号替换为in

在业务需求中,以前开发过程中是一对一关系,要改成一对多的关系,并且要加上权限控制,权限控制可以参考mybatis-plus拦截,这里分享下如何将等于替换成In关系

观察

一般我们要修改字段名称,修改表名,重写ExpressionVisitorAdapter的visit方法就好了,但是不能替换为其他对象
因为在代码中一般都是 whsId = 1 , 通过CCJSqlParserUtil.parseExpression(sql) 转成的对象是 EqualsTo, 尝试了下,直接把需要替换的expression覆盖 ExpressionVisitorAdapter的visit(EqualsTo eualsTo)中的eualsTo对象是行不通的
后面发现sql的解析是一颗树,实现了BinaryExpression接口:

public abstract class BinaryExpression extends ASTNodeAccessImpl implements Expression {

    // 左节点
    private Expression leftExpression;

    // 右节点
    private Expression rightExpression;

	... ...
    
}
多条件时

例如: a = 1 and b = 2 大概是这样这样子的
image.png
所以发现直接操作 EqualsTo 对象是不行的,我们需要操作and的对象 AndExpression

单条件时

当只有 a = 1 时,解析出来是EqualsTo对象,直接把对象全部替换掉就行了

代码如下

@Slf4j
public class JSqlMain {
    
    public static void main(String[] args) throws Exception{

        String sql1 = "whs_id = 1";
        extracted(sql1);

        // 或
        String sql2 = "whs_id = 1 or a = 1";
        extracted(sql2);

        String sql3 = "whs_id = 1 and a = 1 and b = 1 + 1";
        extracted(sql3);
    }

    private static void extracted(String sql) throws JSQLParserException {
        log.info("old sql:[{}]", sql);
        //2、创建解析器
        Expression where = CCJSqlParserUtil.parseExpression(sql);
        Expression expression = CCJSqlParserUtil.parseExpression("aaa in (1, 2 ,344444444)");

        if (where instanceof EqualsTo && ((BinaryExpression)where).getLeftExpression().toString().equals("whs_id")){
            where = expression;
        } else {
            //4、将自定义访问者传入解析后的sql对象  需要自定义字段名,可以在这传进去
            where.accept(new MyJSqlVisitor(expression));
        }

        //5、打印转换后的sql语句
        log.info("new sql:[{}] \n", where);
    }

}
public class MyJSqlVisitor extends ExpressionVisitorAdapter{

    /** 待替换表达式 */
    private Expression expression;

    public MyJSqlVisitor() {
    }

    public MyJSqlVisitor(Expression expression) {
        this.expression = expression;
    }

    @Override
    public void visit(AndExpression andExpression) {
        Expression leftExpression = andExpression.getLeftExpression();
        Expression rightExpression = andExpression.getRightExpression();


        if (Objects.nonNull(leftExpression) && leftExpression instanceof BinaryExpression && ((BinaryExpression) leftExpression).getLeftExpression().toString().equals("whs_id")){
            System.out.println(expression.getClass());
            andExpression.setLeftExpression(expression);
            super.visit(andExpression);
        }

        if (Objects.nonNull(rightExpression) && rightExpression instanceof BinaryExpression && ((BinaryExpression) rightExpression).getLeftExpression().toString().equals("whs_id")){
            System.out.println(expression.getClass());
            andExpression.setRightExpression(expression);
            super.visit(andExpression);
        }

        super.visit(andExpression);
    }

    /**
     * or wsh = 1; 用or开头会走走这里
     * @param orExpression
     */
    @Override
    public void visit(OrExpression orExpression) {
        Expression leftExpression = orExpression.getLeftExpression();
        Expression rightExpression = orExpression.getRightExpression();


        if (Objects.nonNull(leftExpression) && leftExpression instanceof BinaryExpression && ((BinaryExpression) leftExpression).getLeftExpression().toString().equals("whs_id")){
            System.out.println(expression.getClass());
            orExpression.setLeftExpression(expression);
            super.visit(orExpression);
        }

        if (Objects.nonNull(rightExpression) && rightExpression instanceof BinaryExpression && ((BinaryExpression) rightExpression).getLeftExpression().toString().equals("whs_id")){
            System.out.println(expression.getClass());
            orExpression.setRightExpression(expression);
            super.visit(orExpression);
        }

        super.visit(orExpression);
    }

    public void visit(EqualsTo equalsTo){
        // 不能这样, 直接删除
//        if (equalsTo.getLeftExpression().toString().equals("whs_id")){
//            super.visit(expression);
//        }
        super.visit(equalsTo);
    }

}

Ps: 主要提供替换是思路,有什么更好的其他方法替换可以留言

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值