环境搭建:
SpringBoot3.2.5
1. 简介
JSQLParser是一个开源的Java库,它专注于SQL语句的解析与操作。该库能够将SQL语句转换为抽象语法树(AST),使开发者能够轻松地分析、修改和重新生成SQL查询。它是基于 JavaCC 构建的 SQL 语句解析器。它将 SQL 语句转换为可遍历的 Java 类层次结构。
JSQLParser支持多种SQL方言,包括但不限于MySQL、PostgreSQL、Oracle和SQL Server,这使得它能够在多种数据库环境中发挥作用。通过JSQLParser,开发者可以提取SQL语句中的表名、字段名、条件等信息,甚至动态地修改SQL查询,如添加字段或修改条件。
接下来,我将详细的介绍JSQLParser的使用。
2. 实战案例
2.1 环境准备
目前该JSQLParser最新版本是5.1。
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>5.1</version>
</dependency>
引入该包下面我们就可以使用该工具进行SQL语句的解析处理了。
2.2 简单解析
public static void example1() throws Exception {
String sqlStr = "select id, name, age from user where id = 6";
PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
List<SelectItem<?>> selects = select.getSelectItems() ;
System.err.printf("select字段: %s%n", selects) ;
Table table = (Table) select.getFromItem();
System.err.printf("表名: %s%n", table.getName()) ;
}
这里我们解析一个非常简单的SQL语句,运行结果:
select字段: [id, name, age]
表名: user
上面的示例中,我们获取SQL语句中 select子句(查询了哪些字段)以及获取当前查询的表名信息。
为了获得API的指导,我们使用JSQLFormatter可视化Java对象的遍历树:
具体通过如下链接查看:
http://217.160.215.75:8080/jsqlformatter/JSQLFormatter/demo.html
通过该地址,输入SQL后,能展示当前SQL的层次结构。
2.3 查找SQL中所有表
类net.sf.jsqlparser.util.TablesNamesFinder可用于从查询或表达式中返回所有表名。
String sqlStr = "select id, (select name from role r where r.uid = u.id) from user u";
Set<String> tables = TablesNamesFinder.findTables(sqlStr) ;
System.err.println(tables) ;
输出结果
[role, user]
再看下面的SQL同样也能正确的读取所有的表
var sqlStr = "select id, name from user u where u.role_id = (select id from role r where r.name = 'admin')";
var tables = TablesNamesFinder.findTables(sqlStr) ;
System.err.println(tables) ;
该语句也能正确的所有所有的表名。
连接查询
sqlStr = "select id, name, role_name from user u left join role r on(u.role_id = r.id)";
tables = TablesNamesFinder.findTables(sqlStr) ;
输出结果
[role, user]
以上列举了3个示例演示了获取SQL中所有参与的表信息。
2.4 获取where子句
下面我们通过一个比较复杂的SQL语句来解析where子句信息:
public static void example3() throws Exception {
String sqlStr = """
SELECT
id,
name,
role_name
FROM
USER u
LEFT JOIN role r ON ( u.role_id = r.id )
WHERE
name = 'pack'
AND age = 20
AND (email = 'xxx' or state = 1)
""";
PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
Expression where = select.getWhere() ;
System.err.println(where) ;
print(where) ;
}
private static void print(Expression expression) {
if (expression instanceof ComparisonOperator co) {
System.out.println(expression) ;
return ;
}
if (expression instanceof BinaryExpression be) {
Expression leftExpression = be.getLeftExpression() ;
print(leftExpression) ;
Expression rightExpression = be.getRightExpression() ;
print(rightExpression) ;
} else if (expression instanceof ParenthesedExpressionList pe) {
pe.stream().forEach(e -> {
print((Expression) e) ;
}) ;
}
}
输出结果
解析出了where子句中的所有条件。
2.5 构建修改SQL
public static void example5() throws Exception {
Table table = new Table()
.withName("user")
.withAlias(new Alias("t", false)) ;
Column nameColumn = new Column().withColumnName("name");
StringValue nameValue = new StringValue("admin") ;
Expression whereExpression = new EqualsTo()
.withLeftExpression(nameColumn)
.withRightExpression(nameValue) ;
PlainSelect select = new PlainSelect()
.addSelectItems(new Column("id"), new Column("age"), new Column("name"))
.withFromItem(table)
.withWhere(whereExpression);
System.err.println(select.toString()) ;
}
输出SQL语句:
SELECT id, age, name FROM user t WHERE name = 'admin'
使用流畅的API非常轻松的构建任何SQL语句。
2.6 错误处理
public static void example6() throws Exception {
CCJSqlParser parser = new CCJSqlParser(
"select * from user; select from; select * from role" ) ;
Statements statements = parser.Statements() ;
System.err.println(statements.size()) ;
statements.stream().forEach(System.out::println);
}
当我们执行上面的代码后,程序抛出如下错误:
我们的第二条SQL是错误的。
这种情况下,如果你希望即便错了也继续向后解析,那么你可以通过如下的设置:
Statements statements = parser.withErrorRecovery(true)
.Statements() ;
使用withErrorRecovery方法,将继续到下一个语句分隔符并返回一个空语句。
SELECT * FROM user
null
SELECT * FROM role
你也可以如下的方式进行错误的处理:
Statements statements = CCJSqlParserUtil.parseStatements(
"select * from user; select from; select * from role;"
, parser -> parser.withUnsupportedStatements() );
statements.stream().forEach(System.out::println);
输出结果
SELECT * FROM user
select from
SELECT * FROM role
将错误的语句原样返回。
标签:name,神器,role,JSQLParser,SQL,id,select,user From: https://www.cnblogs.com/o-O-oO/p/18681154原创 Springboot实战案例锦集 Spring全家桶实战案例源码