Jsqlparser简单学习

文章目录

学习链接

java设计模式:访问者模式

github使用示例参考

测试 JSqlParser使用示例

JSqlParse(一)基本增删改查语句build
JSqlParse(二)带where的查询语句build

JSqlParser专栏系列教程

jsqlparser:基于抽象语法树(AST)遍历SQL语句的语法元素

Sql解析转换之JSqlParse完整介绍

JSqlParser系列之二代码结构(原)

JSQLPARSER解析SQL知识入门

jsqlparser基本使用

模块

访问者模式

访问者模式理解:

  1. 有固定结构的数据封装类,结构基本不会发生变化。它们都有1个接收访问者的方法。

  2. 访问者针对每1个具体的结构封装类都有1个具体的访问方法。

  3. 在具体的结构封装类接收访问者的方法中,可直接调用访问者针对当前结构类的方法。

  4. 如果封装类结构不是固定的,那么不能使用这种模式

parser模块

statement模块

Expression模块

deparser模块

测试

TestDrop

先创建java对象(结构),使用deparser将java对象转为(得到)sql字符串

java 复制代码
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.drop.Drop;
import net.sf.jsqlparser.util.deparser.DropDeParser;
import org.junit.Test;

public class TestDrop {

    @Test
    public void test_drop() {

        // 创建Drop
        Drop drop = new Drop();

        // 创建Table
        Table table = new Table();
        table.setName("sys_user");

        // 设置drop
        drop.setName(table);
        drop.setType("table");
        drop.setIfExists(true);

        // 最终的sql
        StringBuilder stringBuilder = new StringBuilder();

        // 使用DropDeParser来将java对象(封装了sql信息)转为具体的sql语句
        // (这里的代码是参照StatementDeParser#visit(Drop))
        DropDeParser dropDeParser = new DropDeParser(stringBuilder);
        dropDeParser.deParse(drop);

        // 获取最终的目标sql
        String sql = dropDeParser.getBuffer().toString();

        // DROP table IF EXISTS sys_user
        System.out.println(sql);

    }

    

}

TestSelect

给原来的sql语句添加查询条件:age > 18 and dept_id in (1,2,3)

java 复制代码
package com.zzhua;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectBody;
import net.sf.jsqlparser.util.deparser.ExpressionDeParser;
import net.sf.jsqlparser.util.deparser.SelectDeParser;
import net.sf.jsqlparser.util.deparser.StatementDeParser;
import org.junit.Test;

import java.util.ArrayList;

public class TestSelect {

    @Test
    public void test_select() throws JSQLParserException {

        Statement statement = CCJSqlParserUtil.parse("select id,nick_name from sys_user where id > 10");

        if (statement instanceof Select) {
            System.out.println("select语句");

            Select select = (Select) statement;

            StringBuilder buffer = new StringBuilder();

            // (这里的代码是参照 StatementDeParser#visit(Select))
            // SelectParser实现了SelectVisitor接口, 能够访问PlainSelect、SetOperationList、WithItem
            SelectDeParser selectDeParser = new SelectDeParser();
            selectDeParser.setBuffer(buffer);
            ExpressionDeParser expressionDeParser = new ExpressionDeParser(selectDeParser, buffer);
            selectDeParser.setExpressionVisitor(expressionDeParser);

            // SelectBody接收selectParser的访问(访问的结果会添加到buffer中)
            select.getSelectBody().accept(selectDeParser);

            // 输出原始的sql: SELECT id, nick_name FROM sys_user WHERE id > 10
            System.out.println(buffer);

            SelectBody selectBody = select.getSelectBody();

            if (selectBody instanceof PlainSelect) {

                // 原来的selectBody
                PlainSelect plainSelect = (PlainSelect) select.getSelectBody();

                // age = 18
                EqualsTo equalsTo = new EqualsTo();
                Column ageColumn = new Column("age");
                equalsTo.setLeftExpression(ageColumn);
                equalsTo.setRightExpression(new LongValue(18));

                // 在原来的where条件中拼接上刚刚创建的条件 age=18, 并使用And连接起来
                AndExpression andExpression1 = new AndExpression(plainSelect.getWhere(), equalsTo);

                // dept_id in (1,2,3)
                InExpression inExpression = new InExpression();
                inExpression.setLeftExpression(new Column("dept_id"));
                ExpressionList expressionList = new ExpressionList(new ArrayList<>());
                expressionList.getExpressions().add(new LongValue(1));
                expressionList.getExpressions().add(new LongValue(2));
                expressionList.getExpressions().add(new LongValue(3));
                inExpression.setRightItemsList(expressionList);
                AndExpression andExpression2 = new AndExpression(andExpression1, inExpression);

                // 替换掉原来的where条件
                plainSelect.setWhere(andExpression2);

                // 直接参考StatementDeParser
                StatementDeParser statementDeParser = new StatementDeParser(new StringBuilder());
                Select newSelect = new Select();
                newSelect.setSelectBody(plainSelect);
                statementDeParser.visit(newSelect);

                // 输出sql: SELECT id, nick_name FROM sys_user WHERE id > 10 AND age = 18 AND dept_id IN (1, 2, 3)
                System.out.println(statementDeParser.getBuffer());
            }


        }



    }

}

TestSelectVisitor

java 复制代码
@Slf4j
public class TestSelectVisitor {
    public static void main(String[] args) throws Exception {
        String sqlStr ="SELECT\n" +
                "                su.dept_id `deptId`,\n" +
                "                su.user_id,\n" +
                "                sr.role_id,\n" +
                "                su.user_name,\n" +
                "                sd.dept_name,\n" +
                "                sr.role_name\n" +
                "            FROM\n" +
                "                sys_user AS su\n" +
                "                JOIN sys_dept sd ON su.dept_id = sd.dept_id\n" +
                "                JOIN sys_user_role sur ON sur.user_id = su.user_id\n" +
                "                JOIN sys_role sr ON sur.role_id = sr.role_id\n" +
                "            WHERE\n" +
                "                sd.dept_name = '研发部门'\n" +
                "                AND su.user_name = 'admin'\n" +
                "                AND su.dept_id = 103\n" +
                "                OR sr.role_name = '超级管理员'\n" +
                "                ORDER BY\n" +
                "                sd.create_time DESC";
                
        Select querySql = (Select)CCJSqlParserUtil.parse(sqlStr);

        querySql.getSelectBody().accept(new SelectVisitorAdapter() {
            @Override
            public void visit(PlainSelect plainSelect) {
                log.info("--------------查询列名----------------------------------------");
                plainSelect.getSelectItems().stream().forEach(selectItem -> {
                    selectItem.accept(new SelectItemVisitorAdapter() {
                        @Override
                        public void visit(SelectExpressionItem selectExpressionItem) {
                            log.info(selectExpressionItem.getExpression().toString());
                            if (selectExpressionItem.getAlias()!=null) {
                                log.info("列别名 {}",selectExpressionItem.getAlias().getName());
                            }
                        }
                    });
                });
                log.info("--------------From Table Info----------------------------------------");
                log.info(plainSelect.getFromItem().toString());
                if (plainSelect.getFromItem().getAlias()!=null) {
                    log.info("表别名"+plainSelect.getFromItem().getAlias().getName());
                }
                log.info("--------------Join Table Info----------------------------------------");
                plainSelect.getJoins().stream().forEach(join -> {
                    log.info(join.toString());
                    log.info("关联表:{} ",join.getRightItem());
                    if (join.getRightItem().getAlias()!=null) {
                        log.info("关联表别名:{}",join.getRightItem().getAlias().getName());
                    }
                    log.info("关联条件:{}",join.getOnExpression().toString());
                });
                log.info("--------------Where  Info----------------------------------------");
                plainSelect.getWhere().accept(new ExpressionVisitorAdapter() {
                    @Override
                    public void visitBinaryExpression(BinaryExpression expr) {
                        log.info("表达式:{}",expr.toString());
                        log.info("表达式左侧:{}",expr.getLeftExpression().toString());
                        log.info("表达式右侧:{}",expr.getRightExpression().toString());
                    }
                });
                log.info("--------------增加查询条件----------------------------------------");
                try {
                    plainSelect.setWhere(new AndExpression(CCJSqlParserUtil.parseCondExpression("1=1"),plainSelect.getWhere()));
                } catch (JSQLParserException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        log.info("语句:{}",querySql.toString());

    }
}


/*
--------------查询列名----------------------------------------
su.dept_id
列别名 `deptId`
su.user_id
sr.role_id
su.user_name
sd.dept_name
sr.role_name
--------------From Table Info----------------------------------------
sys_user AS su
表别名su
--------------Join Table Info----------------------------------------
JOIN sys_dept sd ON su.dept_id = sd.dept_id
关联表:sys_dept sd 
关联表别名:sd
关联条件:su.dept_id = sd.dept_id
JOIN sys_user_role sur ON sur.user_id = su.user_id
关联表:sys_user_role sur 
关联表别名:sur
关联条件:sur.user_id = su.user_id
JOIN sys_role sr ON sur.role_id = sr.role_id
关联表:sys_role sr 
关联表别名:sr
关联条件:sur.role_id = sr.role_id
--------------Where  Info----------------------------------------
表达式:sd.dept_name = '研发部门' AND su.user_name = 'admin' AND su.dept_id = 103 OR sr.role_name = '超级管理员'
表达式左侧:sd.dept_name = '研发部门' AND su.user_name = 'admin' AND su.dept_id = 103
表达式右侧:sr.role_name = '超级管理员'
--------------增加查询条件----------------------------------------
语句:SELECT su.dept_id `deptId`, su.user_id, sr.role_id, su.user_name, sd.dept_name, sr.role_name FROM sys_user AS su JOIN sys_dept sd ON su.dept_id = sd.dept_id JOIN sys_user_role sur ON sur.user_id = su.user_id JOIN sys_role sr ON sur.role_id = sr.role_id WHERE 1 = 1 AND sd.dept_name = '研发部门' AND su.user_name = 'admin' AND su.dept_id = 103 OR sr.role_name = '超级管理员' ORDER BY sd.create_time DESC
*/
相关推荐
西岸行者8 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意8 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码8 天前
嵌入式学习路线
学习
毛小茛8 天前
计算机系统概论——校验码
学习
babe小鑫8 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms8 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下8 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。8 天前
2026.2.25监控学习
学习
im_AMBER8 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J8 天前
从“Hello World“ 开始 C++
c语言·c++·学习