SqlUtils.java 4.2 KB

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