Mybatis Plus JSqlParser解析sql語句及JSqlParser安裝步驟
【一】JSqlParser 是什么
JSqlParser 是一個用于解析 SQL 語句的 Java 庫。它可以將 SQL 語句解析為一個 Java 對象樹,允許你以編程的方式對 SQL 語句進行分析、修改和操作。它支持多種 SQL 語句類型,包括但不限于 SELECT、INSERT、UPDATE、DELETE、CREATE、ALTER 等。
例如,對于 SQL 語句 “SELECT column1, column2 FROM table1 WHERE column1 = ‘value’”,JSqlParser 可以將其解析為一個 Java 對象,你可以方便地訪問該對象的各個部分,如 SELECT 子句中的列名(column1 和 column2)、表名(table1)以及 WHERE 子句中的條件(column1 = ‘value’)等。
【二】JSqlParser 的安裝步驟
使用 Maven 進行安裝
(1)在 標簽內添加以下依賴:
<dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>4.4</version> </dependency>
(2)測試案例
import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; public class JSqlParserExample { public static void main(String[] args) throws Exception { String sql = "SELECT * FROM users WHERE id = 1"; Statement statement = CCJSqlParserUtil.parse(sql); System.out.println(statement); } }
首先,我們導入了 CCJSqlParserUtil 和 Statement 類,它們是 JSqlParser 的一部分。
在 main 方法中,我們定義了一個 SQL 語句字符串 sql。
然后,我們使用 CCJSqlParserUtil.parse(sql) 方法將 SQL 語句解析為一個 Statement 對象。
最后,我們將解析后的 Statement 對象打印出來。
【三】使用場景
【1】sql語句解析
你可以使用 JSqlParser 來解析 SQL 語句,以提取其中的關鍵信息。例如,如果你想知道一個 SELECT 語句選擇了哪些列、查詢了哪個表、使用了哪些條件等,可以通過 JSqlParser 進行解析。以下是一個簡單的示例:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectBody; import net.sf.jsqlparser.statement.select.SelectItem; public class JSqlParserExample { public static void main(String[] args) { String sql = "SELECT column1, column2 FROM table1 WHERE column1 = 'value'"; try { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select selectStatement = (Select) statement; SelectBody selectBody = selectStatement.getSelectBody(); if (selectBody instanceof net.sf.jsqlparser.statement.select.PlainSelect) { net.sf.jsqlparser.statement.select.PlainSelect plainSelect = (net.sf.jsqlparser.statement.select.PlainSelect) selectBody; List<SelectItem> selectItems = plainSelect.getSelectItems(); for (SelectItem item : selectItems) { System.out.println("Selected column: " + item); } System.out.println("Table: " + plainSelect.getTable()); System.out.println("Where clause: " + plainSelect.getWhere()); } } } catch (JSQLParserException e) { e.printStackTrace(); } } }
(1)首先,我們使用 CCJSqlParserUtil.parse(sql) 將 SQL 語句解析為一個 Statement 對象。
(2)然后,我們將 Statement 對象轉換為 Select 類型,因為我們知道這是一個 SELECT 語句。
(3)接著,我們通過 getSelectBody() 獲取 SelectBody,并將其轉換為 PlainSelect 類型,因為大多數(shù)簡單的 SELECT 語句是 PlainSelect 類型。
(4)最后,我們可以使用 getSelectItems() 獲取選擇的列,getTable() 獲取表名,getWhere() 獲取 WHERE 子句。
【2】SQL 語句轉換
你可以修改 SQL 語句的某些部分。例如,你可能想要將一個 SELECT 語句中的某些列替換為其他列,或者修改 WHERE 條件。以下是一個示例:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectBody; import net.sf.jsqlparser.statement.select.SelectItem; public class JSqlParserModifyExample { public static void main(String[] args) { String sql = "SELECT column1, column2 FROM table1 WHERE column1 = 'value'"; try { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select selectStatement = (Select) statement; SelectBody selectBody = selectStatement.getSelectBody(); if (selectBody instanceof net.sf.jsqlparser.statement.select.PlainSelect) { net.sf.jsqlparser.statement.select.PlainSelect plainSelect = (net.sf.jsqlparser.statement.select.PlainSelect) selectBody; // 修改列名 plainSelect.getSelectItems().clear(); plainSelect.addSelectItems(CCJSqlParserUtil.parseSelectItem("column3, column4")); // 修改 WHERE 條件 plainSelect.setWhere(CCJSqlParserUtil.parseCondExpression("column3 > 10")); } System.out.println("Modified SQL: " + statement); } } catch (JSQLParserException e) { e.printStackTrace(); } } }
(1)首先,我們按照上述的解析步驟將 SQL 語句解析為 PlainSelect 類型。
(2)然后,我們使用 getSelectItems().clear() 清除原有的選擇項,并使用 addSelectItems() 添加新的選擇項。
(3)最后,我們使用 setWhere() 修改 WHERE 條件。
【3】SQL 語句生成
你可以使用 JSqlParser 來構建新的 SQL 語句。例如,你可以使用其 API 來創(chuàng)建一個 SELECT 語句,而不是手動編寫 SQL 字符串。以下是一個簡單的示例:
import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.GreaterThan; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectExpressionItem; public class JSqlParserCreateExample { public static void main(String[] args) { // 創(chuàng)建表對象 Table table = new Table("table1"); // 創(chuàng)建列對象 Column column1 = new Column("column1"); Column column2 = new Column("column2"); // 創(chuàng)建表達式 column1 = 'value' Expression equalsTo = new EqualsTo(column1, CCJSqlParserUtil.parseExpression("'value'")); // 創(chuàng)建表達式 column2 > 10 Expression greaterThan = new GreaterThan(column2, CCJSqlParserUtil.parseExpression("10")); // 創(chuàng)建 AND 表達式 column1 = 'value' AND column2 > 10 Expression where = new AndExpression(equalsTo, greaterThan); // 創(chuàng)建 SELECT 語句 SelectExpressionItem selectItem1 = new SelectExpressionItem(column1); SelectExpressionItem selectItem2 = new SelectExpressionItem(column2); PlainSelect plainSelect = new PlainSelect(); plainSelect.setSelectItems(List.of(selectItem1, selectItem2)); plainSelect.setTable(table); plainSelect.setWhere(where); Select select = new Select(); select.setSelectBody(plainSelect); System.out.println("Generated SQL: " + select); } }
(1)首先,我們創(chuàng)建表對象和列對象。
(2)然后,我們創(chuàng)建各種表達式,如 EqualsTo 表示等于條件,GreaterThan 表示大于條件,并使用 AndExpression 將它們組合成 WHERE 條件。
(3)接著,我們創(chuàng)建 SelectExpressionItem 作為選擇項。
(4)最后,我們將這些元素組合成 PlainSelect 對象,再將其作為 Select 語句的 SelectBody。
【4】SQL 語句驗證
你可以使用 JSqlParser 來驗證 SQL 語句的語法和結構。例如,在一個 SQL 編輯工具中,你可以使用 JSqlParser 來檢查用戶輸入的 SQL 是否合法。以下是一個簡單的示例:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; public class JSqlParserValidationExample { public static void main(String[] args) { String sql = "SELECT column1, column2 FROM table1 WHERE column1 = 'value'"; try { CCJSqlParserUtil.parse(sql); System.out.println("SQL is valid"); } catch (JSQLParserException e) { System.out.println("SQL is invalid: " + e.getMessage()); } } }
我們使用 CCJSqlParserUtil.parse(sql) 嘗試解析 SQL 語句,如果解析成功,說明 SQL 語句是合法的,否則會拋出 JSQLParserException,表明 SQL 語句存在問題。
【四】在使用 JSqlParser 時,如何處理 SQL 注入攻擊?
以下是在使用 JSqlParser 時處理 SQL 注入攻擊的一些方法:
【1】使用預編譯語句(Prepared Statements)
在 Java 中,使用 JDBC 的預編譯語句是防止 SQL 注入的重要手段,JSqlParser 可以與預編譯語句結合使用。以下是一個簡單的示例:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class JSqlParserWithPreparedStatement { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/your_database"; String user = "username"; String password = "password"; try (Connection connection = DriverManager.getConnection(url, user, password)) { // 假設解析后的 SQL 語句是一個 SELECT 語句 String parsedSql = "SELECT * FROM users WHERE username =?"; try (PreparedStatement preparedStatement = connection.prepareStatement(parsedSql)) { // 設置參數(shù),這里假設用戶輸入來自于用戶界面或其他來源 String userInput = "admin"; preparedStatement.setString(1, userInput); try (ResultSet resultSet = preparedStatement.executeQuery()) { while (resultSet.next()) { // 處理結果集 System.out.println(resultSet.getString("username")); } } } } catch (SQLException e) { e.printStackTrace(); } } }
(1)首先,我們使用 DriverManager.getConnection() 建立數(shù)據(jù)庫連接。
(2)然后,我們定義一個包含占位符 ? 的 SQL 語句,這里的 ? 是預編譯語句的占位符。
(3)使用 connection.prepareStatement() 創(chuàng)建預編譯語句對象。
(4)通過 preparedStatement.setString() 等方法設置參數(shù),這里的參數(shù)會被正確轉義,避免了 SQL 注入的風險。
【2】使用 JSqlParser 對 SQL 語句進行驗證和規(guī)范化
JSqlParser 可以用來檢查 SQL 語句是否符合預期,例如,可以檢查 SQL 語句是否只包含允許的關鍵字和結構。以下是一個簡單的示例:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; public class JSqlParserValidation { public static void main(String[] args) { String sql = "SELECT * FROM users WHERE username = 'admin' AND 1=1; DROP TABLE users;"; try { Statement statement = CCJSqlParserUtil.parse(sql); // 這里可以添加更多的驗證邏輯 // 例如,檢查是否包含不允許的關鍵字,如 DROP、TRUNCATE 等 System.out.println("Parsed SQL: " + statement); } catch (JSQLParserException e) { e.printStackTrace(); } } }
我們使用 CCJSqlParserUtil.parse() 對 SQL 語句進行解析。
在解析后,可以添加額外的驗證邏輯,例如檢查 SQL 語句中是否包含 DROP、TRUNCATE 等危險的關鍵字,以防止惡意用戶刪除或修改數(shù)據(jù)庫結構。
【3】白名單機制
使用白名單來限制 SQL 語句中的表名、列名和操作。以下是一個簡單的示例:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; public class JSqlParserWhiteList { public static final String[] ALLOWED_TABLES = {"users", "products"}; public static void main(String[] args) { String sql = "SELECT * FROM users WHERE username = 'admin'"; try { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select select = (Select) statement; // 假設我們只允許查詢 users 或 products 表 String tableName = select.getSelectBody().toString().split("FROM")[1].trim().split(" ")[0]; if (!isAllowedTable(tableName)) { throw new RuntimeException("Table not allowed"); } System.out.println("Parsed SQL: " + statement); } } catch (JSQLParserException e) { e.printStackTrace(); } } private static boolean isAllowedTable(String tableName) { for (String allowedTable : ALLOWED_TABLES) { if (allowedTable.equalsIgnoreCase(tableName)) { return true; } } return false; } }
我們定義了一個允許的表名數(shù)組 ALLOWED_TABLES。
解析 SQL 語句后,對于 SELECT 語句,我們提取出表名,并檢查它是否在白名單中。
【4】使用參數(shù)化查詢對象
JSqlParser 可以幫助你將 SQL 語句轉換為參數(shù)化查詢對象,然后可以與預編譯語句結合使用。以下是一個簡單的示例:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; public class JSqlParserParameterized { public static void main(String[] args) { String sql = "SELECT * FROM users WHERE username = 'admin' AND age > 20"; try { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select select = (Select) statement; // 假設這里可以提取表達式,如 username = 'admin' 和 age > 20 Expression whereExpression = ((Select) statement).getSelectBody().toString().split("WHERE")[1].trim(); // 這里可以進一步處理表達式,將其轉換為參數(shù)化查詢對象 System.out.println("Parsed Expression: " + whereExpression); } } catch (JSQLParserException e) { e.printStackTrace(); } } }
我們使用 CCJSqlParserUtil.parse() 解析 SQL 語句。
對于 SELECT 語句,我們可以提取 WHERE 子句的表達式,將其作為參數(shù)化查詢對象,然后與預編譯語句結合使用,進一步避免 SQL 注入風險。
【五】使用 JSqlParser 解析復雜的 SQL 語句
【1】思路
(1)導入 JSqlParser 的相關類。
(2)創(chuàng)建一個 SQL 語句的字符串。
(3)使用 CCJSqlParserUtil.parse() 方法將 SQL 語句解析為 Statement 對象。
(4)根據(jù) SQL 語句的不同類型(例如 Select、Insert、Update、Delete),將 Statement 對象進行類型轉換。
(5)對轉換后的對象進行進一步的操作,提取所需的信息。
【2】示例代碼
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectBody; import net.sf.jsqlparser.statement.select.SelectItem; import java.util.List; public class JSqlParserComplexExample { public static void main(String[] args) { String complexSql = "SELECT column1, column2, SUM(column3) AS total FROM table1 WHERE column1 > 10 GROUP BY column1, column2 HAVING SUM(column3) > 100 ORDER BY column1 ASC, column2 DESC"; try { // 將 SQL 語句解析為 Statement 對象 Statement statement = CCJSqlParserUtil.parse(complexSql); // 判斷 Statement 對象是否為 Select 語句 if (statement instanceof Select) { Select selectStatement = (Select) statement; SelectBody selectBody = selectStatement.getSelectBody(); // 提取 Select 語句中的 SelectItems if (selectBody instanceof net.sf.jsqlparser.statement.select.PlainSelect) { net.sf.jsqlparser.statement.select.PlainSelect plainSelect = (net.sf.jsqlparser.statement.select.PlainSelect) selectBody; List<SelectItem> selectItems = plainSelect.getSelectItems(); for (SelectItem item : selectItems) { System.out.println("Select Item: " + item); } // 提取 Where 條件 if (plainSelect.getWhere()!= null) { System.out.println("Where Clause: " + plainSelect.getWhere()); } // 提取 Group By 子句 if (plainSelect.getGroupBy()!= null) { System.out.println("Group By Clause: " + plainSelect.getGroupBy()); } // 提取 Having 子句 if (plainSelect.getHaving()!= null) { System.out.println("Having Clause: " + plainSelect.getHaving()); } // 提取 Order By 子句 if (plainSelect.getOrderByElements()!= null) { System.out.println("Order By Clause: " + plainSelect.getOrderByElements()); } } } } catch (JSQLParserException e) { e.printStackTrace(); } } }
(1)首先,我們導入了 JSqlParser 所需的類,包括異常處理類 JSQLParserException,解析工具類 CCJSqlParserUtil,以及用于表示 SQL 語句的各種類,如 Statement、Select、SelectBody 和 SelectItem 等。
(2)在 main 方法中,我們定義了一個復雜的 SQL 語句字符串 complexSql。
(3)然后,我們使用 CCJSqlParserUtil.parse(complexSql) 方法將這個復雜的 SQL 語句解析為一個 Statement 對象。
(4)接下來,我們檢查這個 Statement 對象是否是 Select 語句(因為我們的示例是一個 SELECT 語句),如果是,我們將其轉換為 Select 類型。
(5)對于 Select 語句,我們進一步提取 SelectBody,并判斷它是否是 PlainSelect 類型,因為大多數(shù)簡單的 SELECT 語句會使用 PlainSelect 結構。
(6)我們可以使用 getSelectItems() 方法獲取 SELECT 子句中的所有選擇項,并遍歷打印它們。
(7)對于 WHERE 子句,我們可以使用 getWhere() 方法獲取條件表達式,如果存在的話。
(8)對于 GROUP BY 子句,我們可以使用 getGroupBy() 方法獲取分組信息,如果存在的話。
(9)對于 HAVING 子句,我們可以使用 getHaving() 方法獲取過濾條件,如果存在的話。
(10)對于 ORDER BY 子句,我們可以使用 getOrderByElements() 方法獲取排序信息,如果存在的話。
如果你要解析的 SQL 語句是 INSERT、UPDATE 或 DELETE 類型,你可以類似地將 Statement 對象轉換為相應的類型,然后使用相應類型的方法提取所需的信息。例如:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.delete.Delete; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.update.Update; public class JSqlParserOtherExamples { public static void main(String[] args) { String insertSql = "INSERT INTO table1 (column1, column2) VALUES (1, 'value')"; String updateSql = "UPDATE table1 SET column1 = 2 WHERE column2 = 'value'"; String deleteSql = "DELETE FROM table1 WHERE column1 = 3"; try { // 解析 INSERT 語句 Statement insertStatement = CCJSqlParserUtil.parse(insertSql); if (insertStatement instanceof Insert) { Insert insert = (Insert) insertStatement; System.out.println("Insert Table: " + insert.getTable()); System.out.println("Insert Columns: " + insert.getColumns()); System.out.println("Insert Values: " + insert.getItemsList()); } // 解析 UPDATE 語句 Statement updateStatement = CCJSqlParserUtil.parse(updateSql); if (updateStatement instanceof Update) { Update update = (Update) updateStatement; System.out.println("Update Table: " + update.getTable()); System.out.println("Update Set Items: " + update.getSets()); System.out.println("Update Where Clause: " + update.getWhere()); } // 解析 DELETE 語句 Statement deleteStatement = CCJSqlParserUtil.parse(deleteSql); if (deleteStatement instanceof Delete) { Delete delete = (Delete) deleteStatement; System.out.println("Delete Table: " + delete.getTable()); System.out.println("Delete Where Clause: " + delete.getWhere()); } } catch (JSQLParserException e) { e.printStackTrace(); } } }
(1)對于 INSERT 語句,我們將 Statement 轉換為 Insert 類型,然后可以使用 getTable() 方法獲取插入的表名,getColumns() 方法獲取插入的列名列表,getItemsList() 方法獲取插入的值列表。
(2)對于 UPDATE 語句,我們將 Statement 轉換為 Update 類型,然后可以使用 getTable() 方法獲取更新的表名,getSets() 方法獲取更新的列和值的映射,getWhere() 方法獲取更新的條件。
(3)對于 DELETE 語句,我們將 Statement 轉換為 Delete 類型,然后可以使用 getTable() 方法獲取刪除的表名,getWhere() 方法獲取刪除的條件。
【六】解析嵌套sql的案例
【1】解析 SQL 并遍歷嵌套結構
解析嵌套的 SQL 語句(如包含子查詢、多層 JOIN 或 WITH 子句)通常需要借助 SQL 解析器工具,將 SQL 轉換為結構化數(shù)據(jù)(如抽象語法樹,AST),然后遞歸遍歷其節(jié)點。以下是具體步驟和示例代碼:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.*; public class NestedSqlParser { public static void main(String[] args) throws JSQLParserException { String sql = "SELECT u.name, (SELECT COUNT(*) FROM orders o WHERE o.user_id = u.id) AS order_count " + "FROM users u " + "WHERE u.id IN (SELECT user_id FROM active_users WHERE status = 'ACTIVE')"; Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select select = (Select) statement; SelectBody selectBody = select.getSelectBody(); processSelectBody(selectBody, 0); // 從嵌套層級 0 開始 } } /** * 遞歸處理 SELECT 語句的嵌套結構 * @param selectBody 當前層級的 SELECT 主體 * @param level 嵌套層級(用于縮進輸出) */ private static void processSelectBody(SelectBody selectBody, int level) { if (selectBody instanceof PlainSelect) { PlainSelect plainSelect = (PlainSelect) selectBody; // 輸出當前層級的 SELECT System.out.println(indent(level) + "SELECT層級: " + level); // 處理子查詢(嵌套 SELECT) for (SelectItem item : plainSelect.getSelectItems()) { if (item instanceof SelectExpressionItem) { SelectExpressionItem exprItem = (SelectExpressionItem) item; if (exprItem.getExpression() instanceof SubSelect) { System.out.println(indent(level) + "發(fā)現(xiàn)子查詢:"); SubSelect subSelect = (SubSelect) exprItem.getExpression(); processSelectBody(subSelect.getSelectBody(), level + 1); // 遞歸處理子查詢 } } } // 處理 WHERE 子句中的子查詢 if (plainSelect.getWhere() != null) { plainSelect.getWhere().accept(new ExpressionVisitorAdapter() { @Override public void visit(SubSelect subSelect) { System.out.println(indent(level) + "WHERE子句中的子查詢:"); processSelectBody(subSelect.getSelectBody(), level + 1); } }); } } else if (selectBody instanceof SetOperationList) { // 處理 UNION/INTERSECT 等集合操作 SetOperationList setOpList = (SetOperationList) selectBody; for (SelectBody body : setOpList.getSelects()) { processSelectBody(body, level + 1); } } } /** 生成縮進字符串 */ private static String indent(int level) { return " ".repeat(level); } }
運行上述代碼,輸出如下:
SELECT層級: 0
發(fā)現(xiàn)子查詢:
SELECT層級: 1
WHERE子句中的子查詢:
SELECT層級: 1
【2】解析邏輯
(1)解析子查詢
(1)子查詢位置
SELECT 列表中的列(如 (SELECT …) AS order_count)。
WHERE 條件中的 IN、EXISTS 等操作符。
FROM 子句中的派生表(如 FROM (SELECT …) AS sub)。
(2)處理方法:通過遞歸遍歷 SelectBody,逐層解析嵌套結構。
(2)處理表達式中的子查詢
使用 ExpressionVisitorAdapter 訪問 WHERE 條件中的子查詢:
plainSelect.getWhere().accept(new ExpressionVisitorAdapter() { @Override public void visit(SubSelect subSelect) { // 處理子查詢 } });
(3)處理 UNION/INTERSECT
對于包含 UNION 的復雜查詢,需處理 SetOperationList:
if (selectBody instanceof SetOperationList) { SetOperationList setOpList = (SetOperationList) selectBody; for (SelectBody body : setOpList.getSelects()) { processSelectBody(body, level + 1); } }
到此這篇關于Mybatis Plus JSqlParser解析sql語句及JSqlParser安裝步驟的文章就介紹到這了,更多相關Mybatis Plus JSqlParser解析sql內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring定時任務@Scheduled注解(cron表達式fixedRate?fixedDelay)
這篇文章主要為大家介紹了Spring定時任務@Scheduled注解(cron表達式fixedRate?fixedDelay)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11解決IntelliJ?IDEA輸出中文顯示為問號問題的有效方法
最近剛學到文件字節(jié)流這里,但輸出中文時,出現(xiàn)了控制臺輸出問號的情況,所以下面這篇文章主要給大家介紹了關于如何解決IntelliJ?IDEA輸出中文顯示為問號問題的有效方法,需要的朋友可以參考下2022-07-07SpringBoot攔截器excludePathPatterns方法不生效的解決方案
這篇文章主要介紹了SpringBoot攔截器excludePathPatterns方法不生效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07基于Java匯總Spock框架Mock靜態(tài)資源經(jīng)驗
這篇文章主要介紹了基于Java匯總Spock框架Mock靜態(tài)資源經(jīng)驗,前面講了?Spock框架Mock對象、方法經(jīng)驗總結,今天分享一下Spock框架中Mock靜態(tài)資源的實踐經(jīng)驗匯總。分成靜態(tài)資源和混合場景,需要的朋友可以參考一下2022-02-02Java concurrency之AtomicReference原子類_動力節(jié)點Java學院整理
AtomicReference是作用是對"對象"進行原子操作。這篇文章主要介紹了Java concurrency之AtomicReference原子類,需要的朋友可以參考下2017-06-06