Browse Source

优化逻辑删除查询字段紧随 where 条件查询

hubin 2 years ago
parent
commit
77d8031b72

+ 23 - 27
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/AbstractMethod.java

@@ -229,37 +229,33 @@ public abstract class AbstractMethod implements Constants {
      * @return String
      */
     protected String sqlWhereEntityWrapper(boolean newLine, TableInfo table) {
+        /**
+         * Wrapper SQL
+         */
+        String ewEmptyOfNormal = "<bind name=\"_sgEs_\" value=\"ew.sqlSegment != null and ew.sqlSegment != ''\"/>";
+        String andSqlSegment = SqlScriptUtils.convertIf(String.format(" AND ${%s}", WRAPPER_SQLSEGMENT), String.format("_sgEs_ and %s", WRAPPER_NONEMPTYOFNORMAL), true);
+        String lastSqlSegment = SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("_sgEs_ and %s", WRAPPER_EMPTYOFNORMAL), true);
+
+        /**
+         * 存在逻辑删除 SQL 注入
+         */
         if (table.isWithLogicDelete()) {
-            String sqlScript = table.getAllSqlWhere(true, true, WRAPPER_ENTITY_DOT);
-            sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY),
-                true);
-            sqlScript += (NEWLINE + table.getLogicDeleteSql(true, true) + NEWLINE);
-            String normalSqlScript = SqlScriptUtils.convertIf(String.format(" AND ${%s}", WRAPPER_SQLSEGMENT),
-                String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT,
-                    WRAPPER_NONEMPTYOFNORMAL), true);
-            normalSqlScript += NEWLINE;
-            normalSqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT),
-                String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT,
-                    WRAPPER_EMPTYOFNORMAL), true);
-            sqlScript += normalSqlScript;
-            sqlScript = SqlScriptUtils.convertChoose(String.format("%s != null", WRAPPER), sqlScript,
-                table.getLogicDeleteSql(false, true));
-            sqlScript = SqlScriptUtils.convertWhere(sqlScript);
-            return newLine ? NEWLINE + sqlScript : sqlScript;
-        } else {
-            String sqlScript = table.getAllSqlWhere(false, true, WRAPPER_ENTITY_DOT);
+            String sqlScript = table.getAllSqlWhere(true, true, true, WRAPPER_ENTITY_DOT);
             sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
-            sqlScript += NEWLINE;
-            sqlScript += SqlScriptUtils.convertIf(String.format(SqlScriptUtils.convertIf(" AND", String.format("%s and %s", WRAPPER_NONEMPTYOFENTITY, WRAPPER_NONEMPTYOFNORMAL), false) + " ${%s}", WRAPPER_SQLSEGMENT),
-                String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT,
-                    WRAPPER_NONEMPTYOFWHERE), true);
-            sqlScript = SqlScriptUtils.convertWhere(sqlScript) + NEWLINE;
-            sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT),
-                String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT,
-                    WRAPPER_EMPTYOFWHERE), true);
-            sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER), true);
+            sqlScript = SqlScriptUtils.convertIf(ewEmptyOfNormal + NEWLINE + sqlScript + NEWLINE + andSqlSegment + NEWLINE + lastSqlSegment,
+                String.format("%s != null", WRAPPER), true);
+            sqlScript = SqlScriptUtils.convertWhere(table.getLogicDeleteSql(false, true) + NEWLINE + sqlScript);
             return newLine ? NEWLINE + sqlScript : sqlScript;
         }
+
+        /**
+         * 普通 SQL 注入
+         */
+        String sqlScript = table.getAllSqlWhere(false, false, true, WRAPPER_ENTITY_DOT);
+        sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
+        sqlScript = SqlScriptUtils.convertWhere(sqlScript + NEWLINE + andSqlSegment) + NEWLINE + lastSqlSegment;
+        sqlScript = SqlScriptUtils.convertIf(ewEmptyOfNormal + NEWLINE + sqlScript, String.format("%s != null", WRAPPER), true);
+        return newLine ? NEWLINE + sqlScript : sqlScript;
     }
 
     protected String sqlOrderBy(TableInfo tableInfo) {

+ 3 - 2
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfo.java

@@ -349,12 +349,13 @@ public class TableInfo implements Constants {
     /**
      * 获取所有的查询的 sql 片段
      *
+     * @param fistAnd             首个条件是否添加 AND 关键字
      * @param ignoreLogicDelFiled 是否过滤掉逻辑删除字段
      * @param withId              是否包含 id 项
      * @param prefix              前缀
      * @return sql 脚本片段
      */
-    public String getAllSqlWhere(boolean ignoreLogicDelFiled, boolean withId, final String prefix) {
+    public String getAllSqlWhere(boolean fistAnd, boolean ignoreLogicDelFiled, boolean withId, final String prefix) {
         final String newPrefix = prefix == null ? EMPTY : prefix;
         String filedSqlScript = fieldList.stream()
             .filter(i -> {
@@ -369,7 +370,7 @@ public class TableInfo implements Constants {
         }
         String newKeyProperty = newPrefix + keyProperty;
         String keySqlScript = keyColumn + EQUALS + SqlScriptUtils.safeParam(newKeyProperty);
-        return SqlScriptUtils.convertIf(keySqlScript, String.format("%s != null", newKeyProperty), false)
+        return SqlScriptUtils.convertIf(fistAnd ? " AND " + keySqlScript : keySqlScript, String.format("%s != null", newKeyProperty), false)
             + NEWLINE + filedSqlScript;
     }
 

+ 1 - 1
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/test/EncryptTest.java

@@ -53,7 +53,7 @@ class EncryptTest {
         System.out.println("----------- AllSqlSet -----------");
         System.out.println(info.getAllSqlSet(true, "ew.entity."));
         System.out.println("----------- AllSqlWhere -----------");
-        System.out.println(info.getAllSqlWhere(true, true, "ew.entity."));
+        System.out.println(info.getAllSqlWhere(false, true, true, "ew.entity."));
     }
 
     @Data