目錄
- 一、引言
- 二、JSQLParser常見類
- 2.1 Class Diagram
- 2.2 Statement
- 2.3 Expression
- 2.4 Select
- 2.5 Update
- 2.6 Delete
- 2.7 Insert
- 2.8 PlainSelect
- 2.9 SetOperationList
- 2.10 ParenthesedSelect
- 2.11 FromItem
- 2.12 Table
- 2.13 ParenthesedFromItem
- 2.14 SelectItem
- 2.15 BinaryExpression
- 2.16 InExpression
- 2.17 ExistsExpression
- 2.18 NotExpression
- 2.19 Parenthesis
- 2.20 Function
- 2.21 EqualsTo
- 2.22 OrExpression
- 2.23 AndExpression
- 2.24 Join
- 2.25 Column
- 2.26 UpdateSet
- 2.27 ExpressionList
- 2.28 ParenthesedExpressionList
- 附:類路徑
一、引言
JSQLParser(GitHub:https://github.com/JSQLParser/JSqlParser)是一個Java語言的SQL語句解析工具,功能十分強大,它可以將SQL語句解析成為Java類的層次結構,還支持改寫SQL,常見的持久層框架MyBatis-Plus就采用它作為SQL解析工具來實現某些功能。
二、JSQLParser常見類
2.1 Class Diagram
2.2 Statement
可以理解為能夠表示任意一種SQL語句的對象,Select、Update、Delete、Insert都是它的子類,例如以下用法:
Statement statement = JsqlParserGlobal.parse(sql);if (statement instanceof Insert) {this.processInsert((Insert) statement, index, sql, obj);
} else if (statement instanceof Select) {this.processSelect((Select) statement, index, sql, obj);
} else if (statement instanceof Update) {this.processUpdate((Update) statement, index, sql, obj);
} else if (statement instanceof Delete) {this.processDelete((Delete) statement, index, sql, obj);
}
2.3 Expression
是JSqlParser庫中的一個核心接口,是用于表示SQL語句中的各種表達式的基類接口,通過調用對象的.toString()
方法,就能看到具體的語句結構。
例如:
- 基本值
LongValue
(整數值)、StringValue
(字符串值)、DoubleValue
(浮點數值)等。
- 列引用
Column
(表示列名,如column_name
或table.column
)。
- 運算符
Addition
(+
)、Subtraction
(-
)、Multiplication
(*
)、Division
(/
)等。
- 函數調用
Function
(如COUNT(*)
、SUBSTRING(str, 1, 2)
)。
- 條件表達式
EqualsTo
(=
)、NotEqualsTo
(<>
或!=
)、GreaterThan
(>
)、LikeExpression
(LIKE
)等。
- 邏輯表達式(BinaryExpression)
AndExpression
(AND
)、OrExpression
(OR
)、NotExpression
(NOT
)。
- 子查詢
SubSelect
(如(SELECT ...)
)。
- Case 表達式
CaseExpression
(CASE WHEN ... THEN ... END
)。
- 其他復雜表達式
CastExpression
(CAST(... AS ...)
)、IntervalExpression
(時間間隔)等。
2.4 Select
用于表示查詢SQL語句,有三個常見子類:PlainSelect,ParenthesedSelect,SetOperationList
2.5 Update
用于表示更新的SQL語句
獲得對應表
Table table = update.getTable();
獲得要更新的值
List<UpdateSet> sets = update.getUpdateSets();
獲取where條件
Expression expression = update.getWhere()
2.6 Delete
用于表示刪除的SQL語句
獲得對應表
Table table = delete.getTable();
獲取where條件
Expression expression = delete.getWhere()
2.7 Insert
用于表示添加SQL語句,有以下幾種常見方法
獲取添加的列
List<Column> columns = insert.getColumns();
獲取添加的值
Values values = insert.getValues();
獲取添加時沖突進行更新的結構
INSERT INTO ... VALUES ...ON DUPLICATE KEY UPDATE ...
List<UpdateSet> duplicateUpdateColumns = insert.getDuplicateUpdateSets();
insert select的結構,獲取select
INSERT ... SELECT ...
Select select = insert.getSelect();
2.8 PlainSelect
用于表示最常規的那種查詢結構,例如:
select...from...join...where...
獲取select后面的結構
List<SelectItem<?>> selectItems = plainSelect.getSelectItems();
獲取select語句的where結構
Expression where = plainSelect.getWhere();
獲取查詢的from后的結構(表,子查詢等)
FromItem fromItem = plainSelect.getFromItem();
存在連接查詢時,獲取連接查詢(left/right/inner)join后的結構
List<Join> joins = plainSelect.getJoins();
2.9 SetOperationList
用于表示多個select語句通過union
,union all
連接在一起的聯合查詢SQL對象
select...from...
union all
select...from...
union all
select...from...
將語句拆分,獲取構成它的若干select
SetOperationList operationList = (SetOperationList) selectBody;
List<Select> selectBodyList = operationList.getSelects();
2.10 ParenthesedSelect
用于表示子查詢,被小括號包裹的一個查詢結構,例如:
(select....from...) as t
“去括號”,得到一個PlainSelect
ParenthesedSelect parenthesedSelect = (ParenthesedSelect) selectBody;
Select select = parenthesedSelect.getSelect();
2.11 FromItem
接口,from
后面的SQL結構,ParenthesedSelect,ParenthesedFromItem,Table都是它的實現
FromItem fromItem = plainSelect.getFromItem();if (fromItem instanceof Table) {}
else if (fromItem instanceof ParenthesedSelect) {}
else if (fromItem instanceof ParenthesedFromItem) {}
2.12 Table
用于表示SQL中的表
2.13 ParenthesedFromItem
小括號包裹的可被查詢的結構,但不是子查詢,不常用,例如小括號包裹的join:
(tab1 join tab2)
2.14 SelectItem
用于表示select語句中,select和from之間的部分,例如:
selectfun(1, 2) as a,(select x from ...) as b,name as c,exists (...) AS d
from t
List<SelectItem<?>> selectItems = plainSelect.getSelectItems();selectItems.forEach(selectItem -> {Expression expression = selectItem.getExpression();if (expression instanceof Select) {}else if (expression instanceof Function) {}else if (expression instanceof ExistsExpression) {}
});
2.15 BinaryExpression
泛指比較符號:and
or
=
>=
=<
,這種結構左右連接著其他結構。EqualsTo,OrExpression,AndExpression都是它的子類。
獲取左右兩側的結構:
BinaryExpression expression = (BinaryExpression) obj;
Expression left = expression.getLeftExpression();
Expression right = expression.getRightExpression();
2.16 InExpression
x in (...)
獲取右側的結構,可能是子查詢或(*,*,*...)
:
InExpression expression = (InExpression) obk;
Expression inExpression = expression.getRightExpression();
2.17 ExistsExpression
exists (...)
獲取右側結構
ExistsExpression expression = (ExistsExpression) obj;
Expression e = expression.getRightExpression() ;
2.18 NotExpression
not,與其他的配合使用,例如:
not in (...)not exists (...)
獲取not
后面的結構,會提取出in
exists
等結構
NotExpression expression = (NotExpression) obj;
Expression e = expression.getExpression();
2.19 Parenthesis
代表小括號()
括起來的結構
(...)
去括號,拿到括號中的結構:
Parenthesis expression = (Parenthesis) obj;
Expression e = expression.getExpression();
2.20 Function
函數結構,通常會獲取參數,對參數進行操作
fun()
ExpressionList<?> parameters = function.getParameters();
if (parameters != null) {parameters.forEach(expression -> {if (expression instanceof Select) {} else if (expression instanceof Function) {} });
}
2.21 EqualsTo
=
2.22 OrExpression
or
2.23 AndExpression
and
2.24 Join
SQL中連接查詢的join結構,從Select中獲得。
獲取join后的結構,一般可能是表也可能是子查詢
FromItem joinItem = join.getRightItem();
判斷是否為隱式內連接
join.isSimple();
判斷是內/左/右連接
join.isRight();
join.isInner();
join.isLeft();
獲取join的on條件
Collection<Expression> originOnExpressions = join.getOnExpressions();
改寫join的on條件
join.setOnExpressions(onExpressions);
2.25 Column
用于表示SQL中的字段對象,例如從一個Insert對象獲取SQL要添加的全部字段:name,age,tenant_id
INSERT INTO t_user (name, age, tenant_id) VALUES ('liming', 15), ('zhaoying', 16)
List<Column> columns = insert.getColumns();
2.26 UpdateSet
UpdateSet是一種類似xx = xx, ...
的結構,出現在update的set
后面
update user set username = 5 where id = 1
List<UpdateSet> sets = update.getUpdateSets();
也能在insert語句處理添加的數據沖突的情況時,出現在ON DUPLICATE KEY UPDATE
后面
INSERT INTO table_name (col1, col2) VALUES (val1, val2)
ON DUPLICATE KEY UPDATE col1 = val3, col2 = col4 + 1;
List<UpdateSet> duplicateUpdateColumns = insert.getDuplicateUpdateSets();
2.27 ExpressionList
Expression列表,本質上是List<Expression>
,當insert語句values
后面批量跟了多組值,就能得到這種結構。
('liming', 15), ('zhaoying', 16)
Values values = insert.getValues();
ExpressionList<Expression> expressions = (ExpressionList<Expression>) values.getExpressions();
2.28 ParenthesedExpressionList
繼承自ExpressionList,本質上也是List<Expression>
,一種帶著括號的Expression結構,例如獲取insert語句values
后面的值就能得到這種結構
('liming', 15)
Values values = insert.getValues();
ExpressionList<Expression> expressions = (ExpressionList<Expression>) values.getExpressions();
if (expressions instanceof ParenthesedExpressionList) {// ParenthesedExpressionList
} else {// ExpressionList
}
原文首發:https://blog.liuzijian.com/post/jsqlparser.html
附:類路徑
net.sf.jsqlparser.statement.Statement
net.sf.jsqlparser.statement.select.Select
net.sf.jsqlparser.statement.update.Update
net.sf.jsqlparser.statement.delete.Delete
net.sf.jsqlparser.statement.insert.Insert
net.sf.jsqlparser.schema.Table
net.sf.jsqlparser.expression.Expression
net.sf.jsqlparser.statement.select.ParenthesedSelect
net.sf.jsqlparser.statement.select.SetOperationList
net.sf.jsqlparser.statement.select.SelectItem
net.sf.jsqlparser.expression.BinaryExpression
net.sf.jsqlparser.expression.operators.relational.InExpression
net.sf.jsqlparser.expression.operators.relational.ExistsExpression
net.sf.jsqlparser.expression.NotExpression
net.sf.jsqlparser.expression.Parenthesis
net.sf.jsqlparser.statement.select.ParenthesedFromItem
net.sf.jsqlparser.statement.select.FromItem
net.sf.jsqlparser.expression.Function
net.sf.jsqlparser.expression.operators.relational.EqualsTo
net.sf.jsqlparser.expression.operators.conditional.OrExpression
net.sf.jsqlparser.expression.operators.conditional.AndExpression
net.sf.jsqlparser.statement.select.Join
net.sf.jsqlparser.schema.Column
net.sf.jsqlparser.expression.operators.relational.ExpressionList
net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList