SqlUtils.java 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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.toolkit;
  17. import com.baomidou.mybatisplus.entity.CountOptimize;
  18. import com.baomidou.mybatisplus.enums.Optimize;
  19. import com.baomidou.mybatisplus.enums.SqlLike;
  20. import com.baomidou.mybatisplus.plugins.pagination.Pagination;
  21. /**
  22. * <p>
  23. * SqlUtils工具类
  24. * </p>
  25. *
  26. * @author Caratacus
  27. * @Date 2016-11-13
  28. */
  29. public class SqlUtils {
  30. public static final String SQL_BASE_COUNT = "SELECT COUNT(1) FROM ( %s ) TOTAL";
  31. private final static SqlFormatter sqlFormatter = new SqlFormatter();
  32. /**
  33. * 获取CountOptimize
  34. *
  35. * @param originalSql 需要计算Count SQL
  36. * @param optimizeType count优化方式
  37. * @param isOptimizeCount 是否需要优化Count
  38. * @return CountOptimize
  39. */
  40. public static CountOptimize getCountOptimize(String originalSql, String optimizeType, String dialectType,
  41. boolean isOptimizeCount) {
  42. CountOptimize countOptimize = CountOptimize.newInstance();
  43. // 获取优化类型
  44. Optimize opType = Optimize.getOptimizeType(optimizeType);
  45. // 调整SQL便于解析
  46. String tempSql = originalSql.replaceAll("(?i)ORDER[\\s]+BY", "ORDER BY").replaceAll("(?i)GROUP[\\s]+BY", "GROUP BY");
  47. String indexOfSql = tempSql.toUpperCase();
  48. // 有排序情况
  49. int orderByIndex = indexOfSql.lastIndexOf("ORDER BY");
  50. // 只针对 ALI_DRUID DEFAULT 这2种情况
  51. if (orderByIndex > -1) {
  52. countOptimize.setOrderBy(false);
  53. }
  54. if (!isOptimizeCount && opType.equals(Optimize.DEFAULT)) {
  55. countOptimize.setCountSQL(String.format(SQL_BASE_COUNT, originalSql));
  56. return countOptimize;
  57. }
  58. switch (opType) {
  59. case ALI_DRUID:
  60. /**
  61. * 调用ali druid方式 插件dbType一定要设置为小写与JdbcConstants保持一致
  62. *
  63. * @see com.alibaba.druid.util.JdbcConstants
  64. */
  65. String aliCountSql = DruidUtils.count(originalSql, dialectType);
  66. countOptimize.setCountSQL(aliCountSql);
  67. break;
  68. case JSQLPARSER:
  69. /**
  70. * 调用JsqlParser方式
  71. */
  72. JsqlParserUtils.jsqlparserCount(countOptimize, originalSql);
  73. break;
  74. default:
  75. StringBuilder countSql = new StringBuilder("SELECT COUNT(1) ");
  76. boolean optimize = false;
  77. if (!indexOfSql.contains("DISTINCT") && !indexOfSql.contains("GROUP BY")) {
  78. int formIndex = indexOfSql.indexOf("FROM");
  79. if (formIndex > -1) {
  80. if (orderByIndex > -1) {
  81. tempSql = tempSql.substring(0, orderByIndex);
  82. countSql.append(tempSql.substring(formIndex));
  83. // 无排序情况
  84. } else {
  85. countSql.append(tempSql.substring(formIndex));
  86. }
  87. // 执行优化
  88. optimize = true;
  89. }
  90. }
  91. if (!optimize) {
  92. // 无优化SQL
  93. countSql.append("FROM ( ").append(originalSql).append(" ) TOTAL");
  94. }
  95. countOptimize.setCountSQL(countSql.toString());
  96. }
  97. return countOptimize;
  98. }
  99. /**
  100. * 查询SQL拼接Order By
  101. *
  102. * @param originalSql 需要拼接的SQL
  103. * @param page page对象
  104. * @param orderBy 是否需要拼接Order By
  105. * @return
  106. */
  107. public static String concatOrderBy(String originalSql, Pagination page, boolean orderBy) {
  108. if (orderBy && StringUtils.isNotEmpty(page.getOrderByField()) && page.isOpenSort()) {
  109. StringBuilder buildSql = new StringBuilder(originalSql);
  110. buildSql.append(" ORDER BY ").append(page.getOrderByField());
  111. buildSql.append(page.isAsc() ? " ASC " : " DESC ");
  112. return buildSql.toString();
  113. }
  114. return originalSql;
  115. }
  116. /**
  117. * 格式sql
  118. *
  119. * @param boundSql
  120. * @param format
  121. * @return
  122. */
  123. public static String sqlFormat(String boundSql, boolean format) {
  124. if (format) {
  125. return sqlFormatter.format(boundSql);
  126. } else {
  127. return boundSql.replaceAll("[\\s]+", " ");
  128. }
  129. }
  130. /**
  131. * <p>
  132. * 用%连接like
  133. * </p>
  134. *
  135. * @param str 原字符串
  136. * @return
  137. */
  138. public static String concatLike(String str, SqlLike type) {
  139. StringBuilder builder = new StringBuilder(str.length() + 3);
  140. switch (type) {
  141. case LEFT:
  142. builder.append("%").append(str);
  143. break;
  144. case RIGHT:
  145. builder.append(str).append("%");
  146. break;
  147. case CUSTOM:
  148. builder.append(str);
  149. break;
  150. default:
  151. builder.append("%").append(str).append("%");
  152. }
  153. return builder.toString();
  154. }
  155. }