項目計划采用數據權限控制,擬采用mybatis加JSqlParser做sql攔截和處理,因此研究了一下JSqlParser的使用,如下:
1. select語句查詢字段
public static List<String> test_select_items(String sql) throws JSQLParserException { CCJSqlParserManager parserManager = new CCJSqlParserManager(); Select select = (Select) parserManager.parse(new StringReader(sql)); PlainSelect plain = (PlainSelect) select.getSelectBody();
//普通查詢,查詢所有字段 List<SelectItem> selectitems = plain.getSelectItems(); List<String> str_items = new ArrayList<String>(); if (selectitems != null) { for (int i = 0; i < selectitems.size(); i++) { str_items.add(selectitems.get(i).toString()); } } return str_items; }
2.獲取表名,注:調用此方法,顯示的表名為去重后的表名
public static List<String> test_select_table(String sql) throws JSQLParserException { Statement statement = (Statement) CCJSqlParserUtil.parse(sql); Select selectStatement = (Select) statement;
//獲取表名 TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); List<String> tableList = tablesNamesFinder .getTableList(selectStatement); return tableList; }
3. 獲取關聯關系
public static List<String> test_select_join(String sql) throws JSQLParserException { Statement statement = (Statement) CCJSqlParserUtil.parse(sql); Select selectStatement = (Select) statement; PlainSelect plain = (PlainSelect) selectStatement.getSelectBody(); List<Join> joinList = plain.getJoins(); List<String> tablewithjoin = new ArrayList<String>(); if (joinList != null) {
//如果關聯后面是子查詢,可以通過便利join集合,獲取FromItem rightItem = join.getRightItem();
//判斷fromItem屬於哪種類型,如果是subSelect類型就是子查詢
for (int i = 0; i < joinList.size(); i++) {
tablewithjoin.add(joinList.get(i).toString());
//注意 , leftjoin rightjoin 等等的to string()區別
}
}
return tablewithjoin;
}
4. 查詢where
public static String test_select_where(String sql) throws JSQLParserException { String columnNames = null; String allColumnNames = null; CCJSqlParserManager parserManager = new CCJSqlParserManager(); Select select = (Select) parserManager.parse(new StringReader(sql)); PlainSelect plain = (PlainSelect) select.getSelectBody(); Expression where_expression = plain.getWhere(); String str = null; if (where_expression != null) { /*str = where_expression.toString(); ExpressionVisitorImpl expressionVisitor = new ExpressionVisitorImpl(); where_expression.accept(expressionVisitor);*/ Set<String> sets = getParser(where_expression); StringBuffer st = new StringBuffer(); sets.stream().forEach(set -> { st.append(set + ","); }); } return str; }
private static Set<String> getParser(Expression expression) {
//初始化接受獲得的字段信息
if (expression instanceof BinaryExpression) {
//獲得左邊表達式
Expression leftExpression = ((BinaryExpression) expression).getLeftExpression();
//獲得左邊表達式為Column對象,則直接獲得列名
if (leftExpression instanceof Column) {
columnName = ((Column) leftExpression).getColumnName();
set.add(columnName);
} else if (leftExpression instanceof InExpression) {
parserInExpression(leftExpression);
} else if (leftExpression instanceof IsNullExpression) {
parserIsNullExpression(leftExpression);
} else if (leftExpression instanceof BinaryExpression) {//遞歸調用
getParser(leftExpression);
} else if (expression instanceof Parenthesis) {//遞歸調用
Expression expression1 = ((Parenthesis) expression).getExpression();
getParser(expression1);
}
//獲得右邊表達式,並分解
Expression rightExpression = ((BinaryExpression) expression).getRightExpression();
if (rightExpression instanceof BinaryExpression) {
parserBinaryExpression(rightExpression);
} else if (rightExpression instanceof InExpression) {
parserInExpression(rightExpression);
} else if (rightExpression instanceof IsNullExpression) {
parserIsNullExpression(rightExpression);
} else if (rightExpression instanceof Parenthesis) {//遞歸調用
Expression expression1 = ((Parenthesis) rightExpression).getExpression();
getParser(expression1);
}
} else if (expression instanceof InExpression) {
parserInExpression(expression);
} else if (expression instanceof IsNullExpression) {
parserIsNullExpression(expression);
} else if (expression instanceof Parenthesis) {//遞歸調用
Expression expression1 = ((Parenthesis) expression).getExpression();
getParser(expression1);
}
return set;
}
/**
* 解析in關鍵字左邊的條件
*
* @param expression
*/
public static void parserInExpression(Expression expression) {
Expression leftExpression = ((InExpression) expression).getLeftExpression();
if (leftExpression instanceof Column) {
columnName = ((Column) leftExpression).getColumnName();
set.add(columnName);
}
}
/**
* 解析is null 和 is not null關鍵字左邊的條件
*
* @param expression
*/
public static void parserIsNullExpression(Expression expression) {
Expression leftExpression = ((IsNullExpression) expression).getLeftExpression();
if (leftExpression instanceof Column) {
columnName = ((Column) leftExpression).getColumnName();
set.add(columnName);
}
}
public static void parserBinaryExpression(Expression expression) {
Expression leftExpression = ((BinaryExpression) expression).getLeftExpression();
if (leftExpression instanceof Column) {
columnName = ((Column) leftExpression).getColumnName();
set.add(columnName);
}
}
5. 獲取from ,如果from關鍵字后面是子查詢語句,則遞歸調用原處理語句
private static String test_select_from(String sql) throws JSQLParserException { CCJSqlParserManager parserManager = new CCJSqlParserManager(); Select select = (Select) parserManager.parse(new StringReader(sql)); // 訪問from PlainSelect plain = (PlainSelect) select.getSelectBody(); // 訪問from FromItem fromItem = plain.getFromItem(); if (fromItem instanceof SubSelect) { System.out.println("-----------------子查詢開始-----------------"); SelectBody selectBody = ((SubSelect) fromItem).getSelectBody(); System.out.println("子查詢"+selectBody.toString()); test_select(selectBody.toString()); System.out.println("-----------------子查詢結束-----------------"); } return fromItem.toString(); }
6.整體執行語句如下:
public static void test_select(String sql) throws JSQLParserException { // *********select body items內容 List<String> str_items = Prasing_Test.test_select_items(sql); System.out.println("查詢字段為:"+str_items.toString()); // **********select table List<String> tableList = Prasing_Test.test_select_table(sql); System.out.println("表名為:"+tableList.toString()); String fromTable = Prasing_Test.test_select_from(sql); System.out.println("from 表名:"+fromTable); // **********select table with join List<String> tablewithjoin = Prasing_Test.test_select_join(sql); for (String join:tablewithjoin) { System.out.println("連接方式為:"+join); } // // *******select where String str = Prasing_Test.test_select_where(sql); System.out.println("where 條件"+str); // // ******select group by List<String> str_groupby = Prasing_Test.test_select_groupby(sql); System.out.println("group by 字段為:"+str_groupby.toString()); // //**************select order by List<String> str_orderby = Prasing_Test.test_select_orderby(sql); System.out.println("order by 條件為:"+str_orderby.toString()); }
后續補充。