diff --git a/docs/zh/core/logic-delete.md b/docs/zh/core/logic-delete.md index 361bef95..f40968e5 100644 --- a/docs/zh/core/logic-delete.md +++ b/docs/zh/core/logic-delete.md @@ -122,12 +122,30 @@ globalConfig.setDeletedValueOfLogicDelete("..."); 此时,我们可以使用 LogicDeleteManager.execWithoutLogicDelete() 方法处理,代码如下: ```java -LogicDeleteManager.execWithoutLogicDelete(() -> - accountMapper.deleteById(1) +LogicDeleteManager.execWithoutLogicDelete(()-> + accountMapper.deleteById(1) ); ``` + 以上代码中,`accountMapper` 会直接对 `Account` 数据进行物理删除,忽略逻辑删除字段配置。 +## 内置逻辑删除处理器 + +MyBatis-Flex 提供了三种字段类型对应的逻辑删除处理器,用户可以根据逻辑删除字段的类型进行设置,它们分别是: + +| 处理器名称 | 对应字段类型 | 数据正常时的值 | 数据被删除时的值 | +|------------------------------|----------|---------|----------| +| IntegerLogicDeleteProcessor | integer | 0 | 1 | +| BooleanLogicDeleteProcessor | tinyint | false | true | +| DateTimeLogicDeleteProcessor | datetime | null | 被删除时间 | +| LongLogicDeleteProcessor | bigint | 0 | 被删除时的时间戳 | + +使用时,只需通过 `LogicDeleteManager` 来设置逻辑删除处理器即可,例如: + +```java +LogicDeleteManager.setProcessor(new DateTimeLogicDeleteProcessor()); +``` + ## 自定义逻辑删除处理功能 在社区中,有许多用户提出希望使用时间类型,当删除时,设置删除字段为`当前时间`,当正常时,设置为 `0` 或者 `null`。 diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/AbstractLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/AbstractLogicDeleteProcessor.java new file mode 100644 index 00000000..e3b6d32f --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/AbstractLogicDeleteProcessor.java @@ -0,0 +1,66 @@ +/* + * 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.QueryCondition; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.table.TableInfo; + +import static com.mybatisflex.core.constant.SqlConsts.EQUALS; + +/** + * 逻辑删除处理器抽象类。 + * + * @author 王帅 + * @since 2023-06-20 + */ +public abstract class AbstractLogicDeleteProcessor 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() + , EQUALS + , getLogicNormalValue())); + } + + /** + * 获取逻辑删除列未删除标记值。 + * + * @return 未删除标记值 + */ + protected abstract Object getLogicNormalValue(); + + /** + * 获取逻辑删除列删除时标记值。 + * + * @return 删除时标记值 + */ + protected abstract Object getLogicDeletedValue(); + +} + + 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 8464e8c6..4ef6d8ee 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 @@ -15,23 +15,41 @@ */ package com.mybatisflex.core.logicdelete; +import com.mybatisflex.core.logicdelete.impl.DefaultLogicDeleteProcessor; + import java.util.function.Supplier; +/** + * 逻辑删除管理器。 + */ public class LogicDeleteManager { - private static LogicDeleteProcessor processor = new DefaultLogicDeleteProcessorImpl(); + private LogicDeleteManager() { + } + + private static LogicDeleteProcessor processor = new DefaultLogicDeleteProcessor(); private static final ThreadLocal skipFlags = new ThreadLocal<>(); + /** + * 获取逻辑删除处理器。 + * + * @return 逻辑删除处理器 + */ public static LogicDeleteProcessor getProcessor() { return processor; } + /** + * 设置逻辑删除处理器。 + * + * @param processor 逻辑删除处理器 + */ public static void setProcessor(LogicDeleteProcessor processor) { LogicDeleteManager.processor = processor; } /** - * 跳过逻辑删除字段处理,直接进行数据库物理操作 + * 跳过逻辑删除字段处理,直接进行数据库物理操作。 */ public static T execWithoutLogicDelete(Supplier supplier) { try { @@ -43,21 +61,25 @@ public class LogicDeleteManager { } /** - * 跳过逻辑删除字段处理 + * 跳过逻辑删除字段处理。 */ public static void skipLogicDelete() { skipFlags.set(Boolean.TRUE); } - /** - * 恢复逻辑删除字段处理 + * 恢复逻辑删除字段处理。 */ public static void restoreLogicDelete() { skipFlags.remove(); } - + /** + * 获取逻辑删除列,返回 {@code null} 表示跳过逻辑删除。 + * + * @param logicDeleteColumn 逻辑删除列 + * @return 逻辑删除列 + */ public static String getLogicDeleteColumn(String logicDeleteColumn) { if (logicDeleteColumn == null) { return null; @@ -66,7 +88,7 @@ public class LogicDeleteManager { if (skipFlag == null) { return logicDeleteColumn; } - return skipFlag ? null : logicDeleteColumn; } + } 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 index 97a39d5b..39895851 100644 --- 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 @@ -19,28 +19,35 @@ 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 + * 用户构建查询正常数据的条件。 + * + * @param logicColumn 逻辑删除列 + * @param dialect 数据库方言 */ String buildLogicNormalCondition(String logicColumn, IDialect dialect); /** - * 用户与构建删除数据时的内容 - * @param logicColumn - * @param dialect + * 用户与构建删除数据时的内容。 + * + * @param logicColumn 逻辑删除列 + * @param dialect 数据库方言 */ String buildLogicDeletedSet(String logicColumn, IDialect dialect); /** - * 用于构建通过 QueryWrapper 查询数据时的内容 - * @param queryWrapper - * @param tableInfo + * 用于构建通过 {@link QueryWrapper} 查询数据时的内容。 + * + * @param queryWrapper 条件构造器 + * @param tableInfo 表信息 */ void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo); + } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/BooleanLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/BooleanLogicDeleteProcessor.java new file mode 100644 index 00000000..bbd18397 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/BooleanLogicDeleteProcessor.java @@ -0,0 +1,45 @@ +/* + * 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.impl; + +import com.mybatisflex.core.logicdelete.AbstractLogicDeleteProcessor; + +/** + * {@link Boolean} 类型的属性对应的逻辑删除处理器。 + * + * @author 王帅 + * @since 2023-06-20 + */ +public class BooleanLogicDeleteProcessor extends AbstractLogicDeleteProcessor { + + /** + * 逻辑删除字段值为 {@code false} 表示数据未删除。 + */ + @Override + protected Object getLogicNormalValue() { + return "FALSE"; + } + + /** + * 逻辑删除字段值为 {@code true} 表示数据删除。 + */ + @Override + protected Object getLogicDeletedValue() { + return "TRUE"; + } + +} \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/DateTimeLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/DateTimeLogicDeleteProcessor.java new file mode 100644 index 00000000..3b33a050 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/DateTimeLogicDeleteProcessor.java @@ -0,0 +1,60 @@ +/* + * 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.impl; + +import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.logicdelete.AbstractLogicDeleteProcessor; +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.table.TableInfo; + +/** + * {@link java.time.LocalDateTime} 类型的属性对应的逻辑删除处理器。 + * + * @author 王帅 + * @since 2023-06-20 + */ +public class DateTimeLogicDeleteProcessor extends AbstractLogicDeleteProcessor { + + @Override + public String buildLogicNormalCondition(String logicColumn, IDialect dialect) { + return dialect.wrap(logicColumn) + " IS NULL"; + } + + @Override + public void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo) { + QueryColumn queryColumn = new QueryColumn(tableInfo.getSchema(), tableInfo.getTableName(), tableInfo.getLogicDeleteColumn()); + queryWrapper.and(queryColumn.isNull()); + } + + /** + * 逻辑删除字段值为 {@code null} 表示数据未删除。 + */ + @Override + protected Object getLogicNormalValue() { + return null; + } + + /** + * 逻辑删除字段值为 {@code NOW()} 表示数据删除,并记录删除时间。 + */ + @Override + protected Object getLogicDeletedValue() { + return "NOW()"; + } + +} \ No newline at end of file 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/impl/DefaultLogicDeleteProcessor.java similarity index 78% rename from mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/DefaultLogicDeleteProcessorImpl.java rename to mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/DefaultLogicDeleteProcessor.java index 4e95ba95..a4f54e55 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/DefaultLogicDeleteProcessorImpl.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/DefaultLogicDeleteProcessor.java @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mybatisflex.core.logicdelete; +package com.mybatisflex.core.logicdelete.impl; import com.mybatisflex.core.FlexGlobalConfig; -import com.mybatisflex.core.constant.SqlConsts; -import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.logicdelete.AbstractLogicDeleteProcessor; import com.mybatisflex.core.query.QueryCondition; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.table.TableInfo; @@ -25,27 +24,19 @@ 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(); - } +/** + * 默认逻辑删除处理器。 + */ +public class DefaultLogicDeleteProcessor extends AbstractLogicDeleteProcessor { @Override public void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo) { queryWrapper.and(QueryCondition.create(tableInfo.getSchema(), tableInfo.getTableName(), tableInfo.getLogicDeleteColumn() - , SqlConsts.EQUALS + , EQUALS , FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete())); } - + @Override protected Object getLogicNormalValue() { Object normalValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete(); if (normalValueOfLogicDelete instanceof Number @@ -55,7 +46,7 @@ public class DefaultLogicDeleteProcessorImpl implements LogicDeleteProcessor { return SINGLE_QUOTE + normalValueOfLogicDelete + SINGLE_QUOTE; } - + @Override protected Object getLogicDeletedValue() { Object deletedValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getDeletedValueOfLogicDelete(); if (deletedValueOfLogicDelete instanceof Number @@ -64,6 +55,7 @@ public class DefaultLogicDeleteProcessorImpl implements LogicDeleteProcessor { } return SINGLE_QUOTE + deletedValueOfLogicDelete + SINGLE_QUOTE; } + } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/IntegerLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/IntegerLogicDeleteProcessor.java new file mode 100644 index 00000000..e62af97f --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/IntegerLogicDeleteProcessor.java @@ -0,0 +1,45 @@ +/* + * 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.impl; + +import com.mybatisflex.core.logicdelete.AbstractLogicDeleteProcessor; + +/** + * {@link Integer} 类型的属性对应的逻辑删除处理器。 + * + * @author 王帅 + * @since 2023-06-20 + */ +public class IntegerLogicDeleteProcessor extends AbstractLogicDeleteProcessor { + + /** + * 逻辑删除字段值为 {@code 0} 表示数据未删除。 + */ + @Override + protected Object getLogicNormalValue() { + return "0"; + } + + /** + * 逻辑删除字段值为 {@code 1} 表示数据删除。 + */ + @Override + protected Object getLogicDeletedValue() { + return "1"; + } + +} \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/LongLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/LongLogicDeleteProcessor.java new file mode 100644 index 00000000..2f05176e --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/LongLogicDeleteProcessor.java @@ -0,0 +1,45 @@ +/* + * 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.impl; + +import com.mybatisflex.core.logicdelete.AbstractLogicDeleteProcessor; + +/** + * {@link Long} 类型的属性对应的逻辑删除处理器。 + * + * @author 王帅 + * @since 2023-06-21 + */ +public class LongLogicDeleteProcessor extends AbstractLogicDeleteProcessor { + + /** + * 逻辑删除字段值为 {@code 0} 表示数据未删除。 + */ + @Override + protected Object getLogicNormalValue() { + return "0"; + } + + /** + * 逻辑删除字段值为 {@code NOW()} 表示数据删除,并记录删除时时间戳。 + */ + @Override + protected Object getLogicDeletedValue() { + return "NOW()"; + } + +} \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/package-info.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/package-info.java new file mode 100644 index 00000000..0e5d3e57 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * 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.impl; \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/package-info.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/package-info.java index 470c1d97..db112303 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/package-info.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/package-info.java @@ -15,6 +15,6 @@ */ /** - * 逻辑删除相关功能 + * 逻辑删除相关功能。 */ package com.mybatisflex.core.logicdelete; \ No newline at end of file diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LogicDeleteTest.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LogicDeleteTest.java new file mode 100644 index 00000000..2974fddb --- /dev/null +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LogicDeleteTest.java @@ -0,0 +1,52 @@ +/* + * 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.coretest; + +import com.mybatisflex.core.dialect.DialectFactory; +import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.logicdelete.LogicDeleteProcessor; +import com.mybatisflex.core.logicdelete.impl.*; +import org.junit.Test; + +/** + * 逻辑删除测试。 + * + * @author 王帅 + * @since 2023-06-20 + */ +@SuppressWarnings("all") +public class LogicDeleteTest { + + private final String logicColumn = "deleted"; + private final IDialect dialect = DialectFactory.getDialect(); + + @Test + public void test() { + print("DefaultLogicDeleteProcessor", new DefaultLogicDeleteProcessor()); + print("BooleanLogicDeleteProcessor", new BooleanLogicDeleteProcessor()); + print("IntegerLogicDeleteProcessor", new IntegerLogicDeleteProcessor()); + print("DateTimeLogicDeleteProcessor", new DateTimeLogicDeleteProcessor()); + print("LongLogicDeleteProcessor", new LongLogicDeleteProcessor()); + } + + public void print(String type, LogicDeleteProcessor processor) { + System.out.println("===== " + type + " ====="); + System.out.println(processor.buildLogicDeletedSet(logicColumn, dialect)); + System.out.println(processor.buildLogicNormalCondition(logicColumn, dialect)); + } + +} \ No newline at end of file