当前位置:   article > 正文

JSqlParser-解析SQL工具类

jsqlparser

 一、介绍 

        JSqlParse是一款很精简的sql解析工具,将sql语句转成Java对象

官网:JSqlParser - Home

用法:可以用于数据权限处理,拦截sql解析改写sql等等。

1. 首先引入jar包

  1. <dependency>
  2. <groupId>com.github.jsqlparser</groupId>
  3. <artifactId>jsqlparser</artifactId>
  4. <version>1.2</version>
  5. </dependency>

二、结构

  1. expression:SQL构建相关类,比如ArrayExpression、CaseExpression、JsonExpression等表达式用于构建SQL。
  2. parser: SQL解析相关类,比如CCJSqlParserUtil主要类。
  3. schema:主要存放数据库schema相关的类 ,比如表、列等。
  4. statement:封装了数据库操作对象,create、insert、delete、select等
  5. util: 各种工具类、不同DB版本、SQL标准等处理类,如SelectUtils、DatabaseType、TablesNamesFinder等

三、工具类封装

网上有相关讲解,但是没有进行整合的例子,我写了个工具类供参考!!!直接上代码

 3.1 定义SQL枚举类型

  1. package com.test.enums;
  2. /**
  3. * @className: SqlType
  4. * @description: SQL 类型
  5. * @version: 1.0
  6. */
  7. public enum SqlType {
  8. ALTER,
  9. CREATEINDEX,
  10. CREATETABLE,
  11. CREATEVIEW,
  12. DELETE,
  13. DROP,
  14. EXECUTE,
  15. INSERT,
  16. MERGE,
  17. REPLACE,
  18. SELECT,
  19. TRUNCATE,
  20. UPDATE,
  21. UPSERT,
  22. NONE
  23. }

3.2 封装工具类

  1. package com.test.utils;
  2. import com.test.enums.SqlType;
  3. import net.sf.jsqlparser.JSQLParserException;
  4. import net.sf.jsqlparser.expression.LongValue;
  5. import net.sf.jsqlparser.parser.CCJSqlParserUtil;
  6. import net.sf.jsqlparser.schema.Table;
  7. import net.sf.jsqlparser.statement.Statement;
  8. import net.sf.jsqlparser.statement.alter.Alter;
  9. import net.sf.jsqlparser.statement.create.index.CreateIndex;
  10. import net.sf.jsqlparser.statement.create.table.CreateTable;
  11. import net.sf.jsqlparser.statement.create.view.CreateView;
  12. import net.sf.jsqlparser.statement.delete.Delete;
  13. import net.sf.jsqlparser.statement.drop.Drop;
  14. import net.sf.jsqlparser.statement.execute.Execute;
  15. import net.sf.jsqlparser.statement.insert.Insert;
  16. import net.sf.jsqlparser.statement.merge.Merge;
  17. import net.sf.jsqlparser.statement.replace.Replace;
  18. import net.sf.jsqlparser.statement.select.FromItem;
  19. import net.sf.jsqlparser.statement.select.Join;
  20. import net.sf.jsqlparser.statement.select.Limit;
  21. import net.sf.jsqlparser.statement.select.PlainSelect;
  22. import net.sf.jsqlparser.statement.select.Select;
  23. import net.sf.jsqlparser.statement.select.SelectBody;
  24. import net.sf.jsqlparser.statement.select.SelectItem;
  25. import net.sf.jsqlparser.statement.select.SubSelect;
  26. import net.sf.jsqlparser.statement.select.WithItem;
  27. import net.sf.jsqlparser.statement.truncate.Truncate;
  28. import net.sf.jsqlparser.statement.update.Update;
  29. import net.sf.jsqlparser.statement.upsert.Upsert;
  30. import net.sf.jsqlparser.util.TablesNamesFinder;
  31. import java.io.StringReader;
  32. import java.util.ArrayList;
  33. import java.util.List;
  34. /**
  35. * @projectName: springboot_demo
  36. * @packageName: com.test.utils
  37. * @description: jsqlparser解析SQL工具类
  38. * PlainSelect类不支持union、union all等请使用SetOperationList接口
  39. * @version: 1.0
  40. */
  41. public class SqlParserTool {
  42. /**
  43. * 由于jsqlparser没有获取SQL类型的原始工具,并且在下面操作时需要知道SQL类型,所以编写此工具方法
  44. *
  45. * @param sql sql语句
  46. * @return sql类型,
  47. * @throws JSQLParserException
  48. */
  49. public static SqlType getSqlType(String sql) throws JSQLParserException {
  50. Statement sqlStmt = CCJSqlParserUtil.parse(new StringReader(sql));
  51. if (sqlStmt instanceof Alter) {
  52. return SqlType.ALTER;
  53. } else if (sqlStmt instanceof CreateIndex) {
  54. return SqlType.CREATEINDEX;
  55. } else if (sqlStmt instanceof CreateTable) {
  56. return SqlType.CREATETABLE;
  57. } else if (sqlStmt instanceof CreateView) {
  58. return SqlType.CREATEVIEW;
  59. } else if (sqlStmt instanceof Delete) {
  60. return SqlType.DELETE;
  61. } else if (sqlStmt instanceof Drop) {
  62. return SqlType.DROP;
  63. } else if (sqlStmt instanceof Execute) {
  64. return SqlType.EXECUTE;
  65. } else if (sqlStmt instanceof Insert) {
  66. return SqlType.INSERT;
  67. } else if (sqlStmt instanceof Merge) {
  68. return SqlType.MERGE;
  69. } else if (sqlStmt instanceof Replace) {
  70. return SqlType.REPLACE;
  71. } else if (sqlStmt instanceof Select) {
  72. return SqlType.SELECT;
  73. } else if (sqlStmt instanceof Truncate) {
  74. return SqlType.TRUNCATE;
  75. } else if (sqlStmt instanceof Update) {
  76. return SqlType.UPDATE;
  77. } else if (sqlStmt instanceof Upsert) {
  78. return SqlType.UPSERT;
  79. } else {
  80. return SqlType.NONE;
  81. }
  82. }
  83. /**
  84. * 获取sql操作接口,与上面类型判断结合使用
  85. * example:
  86. * String sql = "create table a(a string)";
  87. * SqlType sqlType = SqlParserTool.getSqlType(sql);
  88. * if(sqlType.equals(SqlType.SELECT)){
  89. * Select statement = (Select) SqlParserTool.getStatement(sql);
  90. * }
  91. *
  92. * @param sql
  93. * @return
  94. * @throws JSQLParserException
  95. */
  96. public static Statement getStatement(String sql) throws JSQLParserException {
  97. Statement sqlStmt = CCJSqlParserUtil.parse(new StringReader(sql));
  98. return sqlStmt;
  99. }
  100. /**
  101. * 获取tables的表名
  102. *
  103. * @param statement
  104. * @return
  105. */
  106. public static List<String> getTableList(Select statement) {
  107. TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
  108. List<String> tableList = tablesNamesFinder.getTableList(statement);
  109. return tableList;
  110. }
  111. /**
  112. * 获取join层级
  113. *
  114. * @param selectBody
  115. * @return
  116. */
  117. public static List<Join> getJoins(SelectBody selectBody) {
  118. if (selectBody instanceof PlainSelect) {
  119. List<Join> joins = ((PlainSelect) selectBody).getJoins();
  120. return joins;
  121. }
  122. return new ArrayList<Join>();
  123. }
  124. /**
  125. * @param selectBody
  126. * @return
  127. */
  128. public static List<Table> getIntoTables(SelectBody selectBody) {
  129. if (selectBody instanceof PlainSelect) {
  130. List<Table> tables = ((PlainSelect) selectBody).getIntoTables();
  131. return tables;
  132. }
  133. return new ArrayList<Table>();
  134. }
  135. /**
  136. * @param selectBody
  137. * @return
  138. */
  139. public static void setIntoTables(SelectBody selectBody, List<Table> tables) {
  140. if (selectBody instanceof PlainSelect) {
  141. ((PlainSelect) selectBody).setIntoTables(tables);
  142. }
  143. }
  144. /**
  145. * 获取limit值
  146. *
  147. * @param selectBody
  148. * @return
  149. */
  150. public static Limit getLimit(SelectBody selectBody) {
  151. if (selectBody instanceof PlainSelect) {
  152. Limit limit = ((PlainSelect) selectBody).getLimit();
  153. return limit;
  154. }
  155. return null;
  156. }
  157. /**
  158. * 为SQL增加limit值
  159. *
  160. * @param selectBody
  161. * @param l
  162. */
  163. public static void setLimit(SelectBody selectBody, long l) {
  164. if (selectBody instanceof PlainSelect) {
  165. Limit limit = new Limit();
  166. limit.setRowCount(new LongValue(String.valueOf(l)));
  167. ((PlainSelect) selectBody).setLimit(limit);
  168. }
  169. }
  170. /**
  171. * 获取FromItem不支持子查询操作
  172. *
  173. * @param selectBody
  174. * @return
  175. */
  176. public static FromItem getFromItem(SelectBody selectBody) {
  177. if (selectBody instanceof PlainSelect) {
  178. FromItem fromItem = ((PlainSelect) selectBody).getFromItem();
  179. return fromItem;
  180. } else if (selectBody instanceof WithItem) {
  181. SqlParserTool.getFromItem(((WithItem) selectBody).getSelectBody());
  182. }
  183. return null;
  184. }
  185. /**
  186. * 获取子查询
  187. *
  188. * @param selectBody
  189. * @return
  190. */
  191. public static SubSelect getSubSelect(SelectBody selectBody) {
  192. if (selectBody instanceof PlainSelect) {
  193. FromItem fromItem = ((PlainSelect) selectBody).getFromItem();
  194. if (fromItem instanceof SubSelect) {
  195. return ((SubSelect) fromItem);
  196. }
  197. } else if (selectBody instanceof WithItem) {
  198. SqlParserTool.getSubSelect(((WithItem) selectBody).getSelectBody());
  199. }
  200. return null;
  201. }
  202. /**
  203. * 判断是否为多级子查询
  204. *
  205. * @param selectBody
  206. * @return
  207. */
  208. public static boolean isMultiSubSelect(SelectBody selectBody) {
  209. if (selectBody instanceof PlainSelect) {
  210. FromItem fromItem = ((PlainSelect) selectBody).getFromItem();
  211. if (fromItem instanceof SubSelect) {
  212. SelectBody subBody = ((SubSelect) fromItem).getSelectBody();
  213. if (subBody instanceof PlainSelect) {
  214. FromItem subFromItem = ((PlainSelect) subBody).getFromItem();
  215. return subFromItem instanceof SubSelect;
  216. }
  217. }
  218. }
  219. return false;
  220. }
  221. /**
  222. * 获取查询字段
  223. *
  224. * @param selectBody
  225. * @return
  226. */
  227. public static List<SelectItem> getSelectItems(SelectBody selectBody) {
  228. if (selectBody instanceof PlainSelect) {
  229. List<SelectItem> selectItems = ((PlainSelect) selectBody).getSelectItems();
  230. return selectItems;
  231. }
  232. return null;
  233. }
  234. public static void main(String[] args) throws JSQLParserException {
  235. Statement sqlStmt = CCJSqlParserUtil.parse(new StringReader("show databases"));
  236. //获取到子查询语句
  237. String sql = "select * from (select userid from a) a";
  238. SqlType sqlType = SqlParserTool.getSqlType(sql);
  239. if(sqlType.equals(SqlType.SELECT)){
  240. Select statement = (Select) SqlParserTool.getStatement(sql);
  241. SubSelect subSelect = SqlParserTool.getSubSelect(statement.getSelectBody());
  242. System.out.println(subSelect.getSelectBody());
  243. }
  244. }
  245. }

该文章基于原文链接:https://blog.csdn.net/ciqingloveless/article/details/82626304

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/735097
推荐阅读
  

闽ICP备14008679号