TenantSqlParser.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /**
  2. * Copyright (c) 2011-2020, hubin (jobob@qq.com).
  3. * <p>
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. * <p>
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * <p>
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.baomidou.mybatisplus.plugins.parser.tenant;
  17. import java.util.List;
  18. import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
  19. import com.baomidou.mybatisplus.plugins.parser.AbstractJsqlParser;
  20. import net.sf.jsqlparser.expression.BinaryExpression;
  21. import net.sf.jsqlparser.expression.Expression;
  22. import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
  23. import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
  24. import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
  25. import net.sf.jsqlparser.schema.Column;
  26. import net.sf.jsqlparser.schema.Table;
  27. import net.sf.jsqlparser.statement.delete.Delete;
  28. import net.sf.jsqlparser.statement.insert.Insert;
  29. import net.sf.jsqlparser.statement.select.FromItem;
  30. import net.sf.jsqlparser.statement.select.Join;
  31. import net.sf.jsqlparser.statement.select.LateralSubSelect;
  32. import net.sf.jsqlparser.statement.select.PlainSelect;
  33. import net.sf.jsqlparser.statement.select.SelectBody;
  34. import net.sf.jsqlparser.statement.select.SelectExpressionItem;
  35. import net.sf.jsqlparser.statement.select.SetOperationList;
  36. import net.sf.jsqlparser.statement.select.SubJoin;
  37. import net.sf.jsqlparser.statement.select.SubSelect;
  38. import net.sf.jsqlparser.statement.select.ValuesList;
  39. import net.sf.jsqlparser.statement.select.WithItem;
  40. import net.sf.jsqlparser.statement.update.Update;
  41. /**
  42. * <p>
  43. * 租户 SQL 解析( TenantId 行级 )
  44. * </p>
  45. *
  46. * @author hubin
  47. * @since 2017-09-01
  48. */
  49. public class TenantSqlParser extends AbstractJsqlParser {
  50. private TenantHandler tenantHandler;
  51. /**
  52. * select 语句处理
  53. */
  54. @Override
  55. public void processSelectBody(SelectBody selectBody) {
  56. if (selectBody instanceof PlainSelect) {
  57. processPlainSelect((PlainSelect) selectBody);
  58. } else if (selectBody instanceof WithItem) {
  59. WithItem withItem = (WithItem) selectBody;
  60. if (withItem.getSelectBody() != null) {
  61. processSelectBody(withItem.getSelectBody());
  62. }
  63. } else {
  64. SetOperationList operationList = (SetOperationList) selectBody;
  65. if (operationList.getSelects() != null && operationList.getSelects().size() > 0) {
  66. List<SelectBody> plainSelects = operationList.getSelects();
  67. for (SelectBody plainSelect : plainSelects) {
  68. processSelectBody(plainSelect);
  69. }
  70. }
  71. }
  72. }
  73. /**
  74. * <p>
  75. * insert 语句处理
  76. * </p>
  77. */
  78. @Override
  79. public void processInsert(Insert insert) {
  80. if (this.tenantHandler.doTableFilter(insert.getTable().getName())) {
  81. // 过滤退出执行
  82. return;
  83. }
  84. insert.getColumns().add(new Column(this.tenantHandler.getTenantIdColumn()));
  85. if (insert.getSelect() != null) {
  86. processPlainSelect((PlainSelect) insert.getSelect().getSelectBody(), true);
  87. } else if (insert.getItemsList() != null) {
  88. ((ExpressionList) insert.getItemsList()).getExpressions().add(tenantHandler.getTenantId());
  89. } else {
  90. throw new MybatisPlusException("Failed to process multiple-table update, please exclude the tableName or statementId");
  91. }
  92. }
  93. /**
  94. * <p>
  95. * update 语句处理
  96. * </p>
  97. */
  98. @Override
  99. public void processUpdate(Update update) {
  100. List<Table> tableList = update.getTables();
  101. if (null == tableList || tableList.size() >= 2) {
  102. throw new MybatisPlusException("Failed to process multiple-table update, please exclude the statementId");
  103. }
  104. Table table = tableList.get(0);
  105. if (this.tenantHandler.doTableFilter(table.getName())) {
  106. // 过滤退出执行
  107. return;
  108. }
  109. update.setWhere(this.andExpression(table, update.getWhere()));
  110. }
  111. /**
  112. * <p>
  113. * delete 语句处理
  114. * </p>
  115. */
  116. @Override
  117. public void processDelete(Delete delete) {
  118. if (this.tenantHandler.doTableFilter(delete.getTable().getName())) {
  119. // 过滤退出执行
  120. return;
  121. }
  122. delete.setWhere(this.andExpression(delete.getTable(), delete.getWhere()));
  123. }
  124. /**
  125. * <p>
  126. * delete update 语句 where 处理
  127. * </p>
  128. */
  129. protected BinaryExpression andExpression(Table table, Expression where) {
  130. //获得where条件表达式
  131. EqualsTo equalsTo = new EqualsTo();
  132. if (null != where) {
  133. equalsTo.setLeftExpression(new Column(this.tenantHandler.getTenantIdColumn()));
  134. equalsTo.setRightExpression(tenantHandler.getTenantId());
  135. return new AndExpression(equalsTo, where);
  136. }
  137. equalsTo.setLeftExpression(this.getAliasColumn(table));
  138. equalsTo.setRightExpression(tenantHandler.getTenantId());
  139. return equalsTo;
  140. }
  141. /**
  142. * <p>
  143. * 处理 PlainSelect
  144. * </p>
  145. */
  146. protected void processPlainSelect(PlainSelect plainSelect) {
  147. processPlainSelect(plainSelect, false);
  148. }
  149. /**
  150. * <p>
  151. * 处理 PlainSelect
  152. * </p>
  153. *
  154. * @param plainSelect
  155. * @param addColumn 是否添加租户列,insert into select语句中需要
  156. */
  157. protected void processPlainSelect(PlainSelect plainSelect, boolean addColumn) {
  158. FromItem fromItem = plainSelect.getFromItem();
  159. if (fromItem instanceof Table) {
  160. Table fromTable = (Table) fromItem;
  161. if (this.tenantHandler.doTableFilter(fromTable.getName())) {
  162. // 过滤退出执行
  163. return;
  164. }
  165. plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable));
  166. if (addColumn) {
  167. plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(this.tenantHandler.getTenantIdColumn())));
  168. }
  169. } else {
  170. processFromItem(fromItem);
  171. }
  172. List<Join> joins = plainSelect.getJoins();
  173. if (joins != null && joins.size() > 0) {
  174. for (Join join : joins) {
  175. processJoin(join);
  176. processFromItem(join.getRightItem());
  177. }
  178. }
  179. }
  180. /**
  181. * 处理子查询等
  182. */
  183. protected void processFromItem(FromItem fromItem) {
  184. if (fromItem instanceof SubJoin) {
  185. SubJoin subJoin = (SubJoin) fromItem;
  186. if (subJoin.getJoin() != null) {
  187. processJoin(subJoin.getJoin());
  188. }
  189. if (subJoin.getLeft() != null) {
  190. processFromItem(subJoin.getLeft());
  191. }
  192. } else if (fromItem instanceof SubSelect) {
  193. SubSelect subSelect = (SubSelect) fromItem;
  194. if (subSelect.getSelectBody() != null) {
  195. processSelectBody(subSelect.getSelectBody());
  196. }
  197. } else if (fromItem instanceof ValuesList) {
  198. logger.debug("Perform a subquery, if you do not give us feedback");
  199. } else if (fromItem instanceof LateralSubSelect) {
  200. LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
  201. if (lateralSubSelect.getSubSelect() != null) {
  202. SubSelect subSelect = lateralSubSelect.getSubSelect();
  203. if (subSelect.getSelectBody() != null) {
  204. processSelectBody(subSelect.getSelectBody());
  205. }
  206. }
  207. }
  208. }
  209. /**
  210. * 处理联接语句
  211. */
  212. protected void processJoin(Join join) {
  213. if (join.getRightItem() instanceof Table) {
  214. Table fromTable = (Table) join.getRightItem();
  215. if (this.tenantHandler.doTableFilter(fromTable.getName())) {
  216. // 过滤退出执行
  217. return;
  218. }
  219. join.setOnExpression(builderExpression(join.getOnExpression(), fromTable));
  220. }
  221. }
  222. /**
  223. * 处理条件
  224. */
  225. protected Expression builderExpression(Expression expression, Table table) {
  226. //生成字段名
  227. EqualsTo equalsTo = new EqualsTo();
  228. equalsTo.setLeftExpression(this.getAliasColumn(table));
  229. equalsTo.setRightExpression(tenantHandler.getTenantId());
  230. //加入判断防止条件为空时生成 "and null" 导致查询结果为空
  231. if (expression == null) {
  232. return equalsTo;
  233. } else {
  234. if (expression instanceof BinaryExpression) {
  235. BinaryExpression binaryExpression = (BinaryExpression) expression;
  236. if (binaryExpression.getLeftExpression() instanceof FromItem) {
  237. processFromItem((FromItem) binaryExpression.getLeftExpression());
  238. }
  239. if (binaryExpression.getRightExpression() instanceof FromItem) {
  240. processFromItem((FromItem) binaryExpression.getRightExpression());
  241. }
  242. }
  243. return new AndExpression(equalsTo, expression);
  244. }
  245. }
  246. /**
  247. * <p>
  248. * 字段是否添加别名设置
  249. * </p>
  250. *
  251. * @param table 表对象
  252. * @return 字段
  253. */
  254. protected Column getAliasColumn(Table table) {
  255. if (null == table.getAlias()) {
  256. return new Column(this.tenantHandler.getTenantIdColumn());
  257. }
  258. StringBuilder column = new StringBuilder();
  259. column.append(table.getAlias().getName());
  260. column.append(".");
  261. column.append(this.tenantHandler.getTenantIdColumn());
  262. return new Column(column.toString());
  263. }
  264. public TenantHandler getTenantHandler() {
  265. return tenantHandler;
  266. }
  267. public void setTenantHandler(TenantHandler tenantHandler) {
  268. this.tenantHandler = tenantHandler;
  269. }
  270. }