当前位置: 首页 > news >正文

Jsqlparser简单学习

文章目录

    • 学习链接
    • 模块
      • 访问者模式
      • parser模块
      • statement模块
      • Expression模块
      • deparser模块
    • 测试
      • TestDrop
      • TestSelect
      • TestSelectVisitor

学习链接

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字符串

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 {@Testpublic void test_drop() {// 创建DropDrop drop = new Drop();// 创建TableTable table = new Table();table.setName("sys_user");// 设置dropdrop.setName(table);drop.setType("table");drop.setIfExists(true);// 最终的sqlStringBuilder stringBuilder = new StringBuilder();// 使用DropDeParser来将java对象(封装了sql信息)转为具体的sql语句// (这里的代码是参照StatementDeParser#visit(Drop))DropDeParser dropDeParser = new DropDeParser(stringBuilder);dropDeParser.deParse(drop);// 获取最终的目标sqlString sql = dropDeParser.getBuffer().toString();// DROP table IF EXISTS sys_userSystem.out.println(sql);}}

TestSelect

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

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 {@Testpublic 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、WithItemSelectDeParser 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 > 10System.out.println(buffer);SelectBody selectBody = select.getSelectBody();if (selectBody instanceof PlainSelect) {// 原来的selectBodyPlainSelect plainSelect = (PlainSelect) select.getSelectBody();// age = 18EqualsTo 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);// 直接参考StatementDeParserStatementDeParser 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

@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() {@Overridepublic void visit(PlainSelect plainSelect) {log.info("--------------查询列名----------------------------------------");plainSelect.getSelectItems().stream().forEach(selectItem -> {selectItem.accept(new SelectItemVisitorAdapter() {@Overridepublic 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() {@Overridepublic 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
*/

相关文章:

Jsqlparser简单学习

文章目录 学习链接模块访问者模式parser模块statement模块Expression模块deparser模块 测试TestDropTestSelectTestSelectVisitor 学习链接 java设计模式&#xff1a;访问者模式 github使用示例参考 测试 JSqlParser使用示例 JSqlParse&#xff08;一&#xff09;基本增删改…...

IC验证——perl脚本ccode_standard——c代码寄存器配置标准化

目录 1 脚本名称 2 脚本路径 3 脚本参数说明 4 脚本操作说明 5 脚本代码 1 脚本名称 ccode_standard 2 脚本路径 /scripts/bin/ccode_standard 3 脚本参数说明 次序 参数名 说明 1 address (./rfdig&#xff1b;.&#xff1b;..&#xff1b;./boot) 指定脚本执行路…...

Qt单个字符判断

1.相关说明 字符的Unicode编码、单个字符的判断 2.界面绘制 3.相关主要代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui;…...

通过OpenIddict设计一个授权服务器02-创建asp.net项目

在这一部分中&#xff0c;我们将创建一个ASPNET核心项目&#xff0c;作为我们授权服务器的最低设置。我们将使用MVC来提供页面&#xff0c;并将身份验证添加到项目中&#xff0c;包括一个基本的登录表单。 创建一个空的asp.net core项目 正如前一篇文章中所说&#xff0c;授权…...

2.6、云负载均衡产品详述

一、定义 弹性负载均衡(Elastic Load Balance&#xff0c;简称ELB)可将来自公网的访问流量分发到后端云主机&#xff0c;可选多种负载均衡策略&#xff0c;并支持自动检测云主机健康状况&#xff0c;消除单点故障&#xff0c;保障应用系统的高可用。 二、产品架构 1&am…...

黑马程序员 Docker笔记

本篇学习笔记文档对应B站视频&#xff1a; 同学们&#xff0c;在前两天我们学习了Linux操作系统的常见命令以及如何在Linux上部署一个单体项目。大家想一想自己最大的感受是什么&#xff1f; 我相信&#xff0c;除了个别天赋异禀的同学以外&#xff0c;大多数同学都会有相同的…...

游戏素材永不缺,免费在线AI工具Scenario功能齐全,简单易用

Scenario是一个在线的AI驱动的工具&#xff0c;主要用于游戏艺术创作。它提供了一套全面的功能&#xff0c;旨在帮助游戏开发者创建与其独特风格和艺术方向相符的独特、高质量的游戏艺术。Scenario的突出特点之一是它的微调能力&#xff0c;允许用户根据独特的风格和艺术方向训…...

ChatGPT和文心一言哪个好用?

#ChatGPT 和文心一言哪个更好用&#xff1f;# 在当今信息爆炸的时代&#xff0c;人们对于文本生成和创作工具的需求越来越高。在这个背景下&#xff0c;ChatGPT和文心一言作为备受瞩目的工具&#xff0c;各自拥有独特的功能和用途。在本文中&#xff0c;我们将深入探讨这两个工…...

纯c++简易的迷宫小游戏

一个用c写的黑框框迷宫 适合新手入门学习 也适合大学生小作业 下面附上代码 总体思路 初始化游戏界面&#xff1a;设置迷宫的大小&#xff08;WIDTH和HEIGH&#xff09;&#xff0c;生成迷宫地图&#xff08;map&#xff09;&#xff0c;包括墙壁、空地、起点和终点。显示…...

基于python舆情分析可视化系统+情感分析+爬虫+机器学习(源码)✅

大数据毕业设计&#xff1a;Python招聘数据采集分析可视化系统✅ 毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&…...

2024年1月16日Arxiv热门NLP大模型论文:Multi-Candidate Speculative Decoding

大幅提速NLP任务&#xff0c;无需牺牲准确性&#xff01;南京大学提出新算法&#xff0c;大幅提升AI文本生成效率飞跃 引言&#xff1a;探索大型语言模型的高效文本生成 在自然语言处理&#xff08;NLP&#xff09;的领域中&#xff0c;大型语言模型&#xff08;LLMs&#xf…...

AI对决:ChatGPT与文心一言的比较

文章目录 引言ChatGPT与文心一言的比较Chatgpt的看法文心一言的看法Copilot的观点chatgpt4.0的回答 模型的自我评价自我评价 ChatGPT的优势在这里插入图片描述 文心一言的优势AI技术发展趋势总结 引言 在过去的几年里&#xff0c;人工智能&#xff08;AI&#xff09;技术取得了…...

uni-app引用矢量库图标

矢量库引用 导入黑色图标 1.生成连接&#xff0c;下载样式 2.导入项目&#xff08;字体样式&#xff09; 3.引入css样式 4.替换font-face 5.使用图标&#xff08;字体图标&#xff0c;只有黑色&#xff09; 导入彩色图标 1.安装插件 npm install -g iconfont-tools2.…...

Android的setContentView流程

一.Activity里面的mWindow是啥 在ActivityThread的performLaunchActivity方法里面&#xff1a; private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {ActivityInfo aInfo r.activityInfo;if (r.packageInfo null) {r.packageInfo getP…...

【加速排坑】docker设置国内image镜像源

第零步&#xff0c;查看阿里最新的镜像源&#xff1a;https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 第一步&#xff1a;在/etc/docker/daemon.json中添加镜像源 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-m…...

el-table嵌套两层el-dropdown-menu导致样式错乱

问题&#xff1a; 解决方式&#xff1a; <el-table-column label"操作" fixed"right" width"132" align"center"><template slot-scope"scope"><div v-if"scope.row._index ! 合计"><el-d…...

自动化测试:fixture学得好,Pytest测试框架用到老

在pytest中&#xff0c;fixture是一种非常有用的特性&#xff0c;它允许我们在测试函数中注入数据或状态&#xff0c;以便进行测试。而参数化则是fixture的一个特性&#xff0c;它允许我们将不同的数据传递给fixture&#xff0c;从而进行多次测试。 本文将介绍如何在pytest中使…...

Linux上常用网络操作

主机名配置 hostname 查看主机名 hostname xxx 修改主机名 重启后无效 如果想要永久生效&#xff0c;可以修改/etc/sysconfig/network文件 IP地址配置 ifconfig 查看(修改)ip地址(重启后无效) ifconfig eth0 192.168.12.22 修改ip地址 如果想要永久生效,修改 /etc/sysco…...

POI:对Excel的基本读操作 整理2

1 简单读取操作 public class ExcelRead {String PATH "D:\\Idea-projects\\POI\\POI_projects";// 读取的一系列方法// ...... } 因为07版本和03版本操作流程大差不差&#xff0c;所以这边就以03版本为例 Testpublic void testRead03() throws IOException {//获取…...

LeetCode每周五题_2024/01/15~01/19

文章目录 82. 删除排序链表中的重复元素 II题目题解 2744. 最大字符串配对数目题目题解 82. 删除排序链表中的重复元素 II 82. 删除排序链表中的重复元素 II 题目 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...