From dc79a7b715611ee9b504c8522fd2d5ad6227c29b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Mon, 19 Jun 2023 19:39:09 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E9=80=BB=E8=BE=91=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=99=A8=EF=BC=9ALogicDeleteProcessor.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh/core/logic-delete.md | 37 +++++++++- .../core/dialect/impl/CommonsDialectImpl.java | 39 +++-------- .../DefaultLogicDeleteProcessorImpl.java | 69 +++++++++++++++++++ .../core/logicdelete/LogicDeleteManager.java | 23 +++++++ .../logicdelete/LogicDeleteProcessor.java | 46 +++++++++++++ .../com/mybatisflex/core/table/TableInfo.java | 14 ++-- 6 files changed, 192 insertions(+), 36 deletions(-) create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/DefaultLogicDeleteProcessorImpl.java create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteProcessor.java diff --git a/docs/zh/core/logic-delete.md b/docs/zh/core/logic-delete.md index 16a93059..926dcef7 100644 --- a/docs/zh/core/logic-delete.md +++ b/docs/zh/core/logic-delete.md @@ -81,4 +81,39 @@ LogicDeleteManager.execWithoutLogicDelete(() -> accountMapper.deleteById(1) ); ``` -以上代码中,`accountMapper` 会直接对 `Account` 数据进行物理删除,忽略逻辑删除字段配置。 \ No newline at end of file +以上代码中,`accountMapper` 会直接对 `Account` 数据进行物理删除,忽略逻辑删除字段配置。 + +## 自定义逻辑删除处理能力 + +在社区中,有许多用户提出希望使用时间类型,当删除时,设置删除字段为`当前时间`,当正常时,设置为 `0` 或者 `null`。 +那么,我们可以为 `LogicDeleteManager` 设置一个新的 `LogicDeleteProcessor`: + +`LogicDeleteProcessor` 接口的内容如下: + +```java +public interface LogicDeleteProcessor { + + /** + * 用户构建查询正常数据的条件 + * @param logicColumn + * @param dialect + */ + String buildLogicNormalCondition(String logicColumn, IDialect dialect); + + /** + * 用户与构建删除数据时的内容 + * @param logicColumn + * @param dialect + */ + String buildLogicDeletedSet(String logicColumn, IDialect dialect); + + /** + * 用于构建通过 QueryWrapper 查询数据时的内容 + * @param queryWrapper + * @param tableInfo + */ + void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo); +} +``` + +具体实现可以参考:[DefaultLogicDeleteProcessorImpl](DefaultLogicDeleteProcessorImpl) \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java index 960a333d..3f7b99f9 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java @@ -15,11 +15,11 @@ */ package com.mybatisflex.core.dialect.impl; -import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.dialect.IDialect; import com.mybatisflex.core.dialect.KeywordWrap; import com.mybatisflex.core.dialect.LimitOffsetProcessor; import com.mybatisflex.core.exception.FlexExceptions; +import com.mybatisflex.core.logicdelete.LogicDeleteManager; import com.mybatisflex.core.query.*; import com.mybatisflex.core.row.Row; import com.mybatisflex.core.row.RowCPI; @@ -492,7 +492,7 @@ public class CommonsDialectImpl implements IDialect { @Override public String forDeleteEntityById(TableInfo tableInfo) { - String logicDeleteColumn = tableInfo.getLogicDeleteColumn(); + String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip(); Object[] tenantIdArgs = tableInfo.buildTenantIdArgs(); //正常删除 if (StringUtil.isBlank(logicDeleteColumn)) { @@ -518,7 +518,6 @@ public class CommonsDialectImpl implements IDialect { sql.append(wrap(primaryKeys[i])).append(EQUALS_PLACEHOLDER); } -// sql.append(AND).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicNormalValue()); sql.append(AND).append(buildLogicNormalCondition(logicDeleteColumn)); //租户ID @@ -532,7 +531,7 @@ public class CommonsDialectImpl implements IDialect { @Override public String forDeleteEntityBatchByIds(TableInfo tableInfo, Object[] primaryValues) { - String logicDeleteColumn = tableInfo.getLogicDeleteColumn(); + String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip(); Object[] tenantIdArgs = tableInfo.buildTenantIdArgs(); //正常删除 @@ -594,7 +593,7 @@ public class CommonsDialectImpl implements IDialect { @Override public String forDeleteEntityBatchByQuery(TableInfo tableInfo, QueryWrapper queryWrapper) { - String logicDeleteColumn = tableInfo.getLogicDeleteColumn(); + String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip(); //正常删除 if (StringUtil.isBlank(logicDeleteColumn)) { @@ -663,7 +662,7 @@ public class CommonsDialectImpl implements IDialect { } //逻辑删除条件,已删除的数据不能被修改 - String logicDeleteColumn = tableInfo.getLogicDeleteColumn(); + String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip(); if (StringUtil.isNotBlank(logicDeleteColumn)) { sql.append(AND).append(buildLogicNormalCondition(logicDeleteColumn)); } @@ -814,7 +813,7 @@ public class CommonsDialectImpl implements IDialect { } //逻辑删除的情况下,需要添加逻辑删除的条件 - String logicDeleteColumn = tableInfo.getLogicDeleteColumn(); + String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip(); if (StringUtil.isNotBlank(logicDeleteColumn)) { sql.append(AND).append(buildLogicNormalCondition(logicDeleteColumn)); } @@ -836,7 +835,7 @@ public class CommonsDialectImpl implements IDialect { sql.append(WHERE); String[] primaryKeys = tableInfo.getPrimaryKeys(); - String logicDeleteColumn = tableInfo.getLogicDeleteColumn(); + String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip(); Object[] tenantIdArgs = tableInfo.buildTenantIdArgs(); if (StringUtil.isNotBlank(logicDeleteColumn) || ArrayUtil.isNotEmpty(tenantIdArgs)) { sql.append(BRACKET_LEFT); @@ -975,34 +974,14 @@ public class CommonsDialectImpl implements IDialect { return sb.toString(); } - protected String buildLogicNormalCondition(String logicColumn) { - return wrap(logicColumn) + EQUALS + getLogicNormalValue(); + return LogicDeleteManager.getProcessor().buildLogicNormalCondition(logicColumn,this); } protected String buildLogicDeletedSet(String logicColumn) { - return wrap(logicColumn) + EQUALS + getLogicDeletedValue(); + return LogicDeleteManager.getProcessor().buildLogicDeletedSet(logicColumn,this); } - protected Object getLogicNormalValue() { - Object normalValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete(); - if (normalValueOfLogicDelete instanceof Number - || normalValueOfLogicDelete instanceof Boolean) { - return normalValueOfLogicDelete; - } - return SINGLE_QUOTE + normalValueOfLogicDelete + SINGLE_QUOTE; - } - - - protected Object getLogicDeletedValue() { - Object deletedValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getDeletedValueOfLogicDelete(); - if (deletedValueOfLogicDelete instanceof Number - || deletedValueOfLogicDelete instanceof Boolean) { - return deletedValueOfLogicDelete; - } - return SINGLE_QUOTE + deletedValueOfLogicDelete + SINGLE_QUOTE; - } - } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/DefaultLogicDeleteProcessorImpl.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/DefaultLogicDeleteProcessorImpl.java new file mode 100644 index 00000000..4e95ba95 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/DefaultLogicDeleteProcessorImpl.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.core.logicdelete; + +import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.constant.SqlConsts; +import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.query.QueryCondition; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.table.TableInfo; + +import static com.mybatisflex.core.constant.SqlConsts.EQUALS; +import static com.mybatisflex.core.constant.SqlConsts.SINGLE_QUOTE; + +public class DefaultLogicDeleteProcessorImpl implements LogicDeleteProcessor { + + @Override + public String buildLogicNormalCondition(String logicColumn, IDialect dialect) { + return dialect.wrap(logicColumn) + EQUALS + getLogicNormalValue(); + } + + + @Override + public String buildLogicDeletedSet(String logicColumn, IDialect dialect) { + return dialect.wrap(logicColumn) + EQUALS + getLogicDeletedValue(); + } + + @Override + public void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo) { + queryWrapper.and(QueryCondition.create(tableInfo.getSchema(), tableInfo.getTableName(), tableInfo.getLogicDeleteColumn() + , SqlConsts.EQUALS + , FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete())); + } + + + protected Object getLogicNormalValue() { + Object normalValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete(); + if (normalValueOfLogicDelete instanceof Number + || normalValueOfLogicDelete instanceof Boolean) { + return normalValueOfLogicDelete; + } + return SINGLE_QUOTE + normalValueOfLogicDelete + SINGLE_QUOTE; + } + + + protected Object getLogicDeletedValue() { + Object deletedValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getDeletedValueOfLogicDelete(); + if (deletedValueOfLogicDelete instanceof Number + || deletedValueOfLogicDelete instanceof Boolean) { + return deletedValueOfLogicDelete; + } + return SINGLE_QUOTE + deletedValueOfLogicDelete + SINGLE_QUOTE; + } +} + + diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteManager.java index 73f8753c..8464e8c6 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteManager.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteManager.java @@ -1,11 +1,34 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.mybatisflex.core.logicdelete; import java.util.function.Supplier; public class LogicDeleteManager { + private static LogicDeleteProcessor processor = new DefaultLogicDeleteProcessorImpl(); private static final ThreadLocal skipFlags = new ThreadLocal<>(); + public static LogicDeleteProcessor getProcessor() { + return processor; + } + + public static void setProcessor(LogicDeleteProcessor processor) { + LogicDeleteManager.processor = processor; + } /** * 跳过逻辑删除字段处理,直接进行数据库物理操作 diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteProcessor.java new file mode 100644 index 00000000..97a39d5b --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/LogicDeleteProcessor.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.core.logicdelete; + +import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.table.TableInfo; + +public interface LogicDeleteProcessor { + + /** + * 用户构建查询正常数据的条件 + * @param logicColumn + * @param dialect + */ + String buildLogicNormalCondition(String logicColumn, IDialect dialect); + + /** + * 用户与构建删除数据时的内容 + * @param logicColumn + * @param dialect + */ + String buildLogicDeletedSet(String logicColumn, IDialect dialect); + + /** + * 用于构建通过 QueryWrapper 查询数据时的内容 + * @param queryWrapper + * @param tableInfo + */ + void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo); +} + + diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java index bd4dc81d..69be0562 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java @@ -164,10 +164,13 @@ public class TableInfo { this.dataSource = dataSource; } - public String getLogicDeleteColumn() { + public String getLogicDeleteColumnOrSkip() { return LogicDeleteManager.getLogicDeleteColumn(logicDeleteColumn); } + public String getLogicDeleteColumn() { + return logicDeleteColumn; + } public void setLogicDeleteColumn(String logicDeleteColumn) { this.logicDeleteColumn = logicDeleteColumn; } @@ -666,9 +669,10 @@ public class TableInfo { } //逻辑删除 - if (StringUtil.isNotBlank(getLogicDeleteColumn())) { - queryWrapper.and(QueryCondition.create(schema, tableName, logicDeleteColumn, SqlConsts.EQUALS - , FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete())); + if (StringUtil.isNotBlank(getLogicDeleteColumnOrSkip())) { +// queryWrapper.and(QueryCondition.create(schema, tableName, logicDeleteColumn, SqlConsts.EQUALS +// , FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete())); + LogicDeleteManager.getProcessor().buildQueryCondition(queryWrapper,this); } //多租户 @@ -986,7 +990,7 @@ public class TableInfo { * @param entityObject */ public void initLogicDeleteValueIfNecessary(Object entityObject) { - if (StringUtil.isBlank(getLogicDeleteColumn())) { + if (StringUtil.isBlank(getLogicDeleteColumnOrSkip())) { return; }