From bc53d5bfffda10ace055817f0249995296675ac1 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Mon, 16 Jun 2025 22:29:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(extension/crud):=20=E6=96=B0=E5=A2=9E=20Ap?= =?UTF-8?q?i.BATCH=5FDELETE=20=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=EF=BC=8C=E6=8B=86=E5=88=86=E5=8D=95=E4=B8=AA?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=92=8C=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../starter/data/mp/mapper/BaseMapper.java | 112 ++++++++++++++++++ .../CrudRequestMappingHandlerMapping.java | 6 +- .../controller/AbstractCrudController.java | 18 ++- .../starter/extension/crud/enums/Api.java | 5 + .../crud/service/CrudServiceImpl.java | 2 +- 5 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/mapper/BaseMapper.java diff --git a/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/mapper/BaseMapper.java b/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/mapper/BaseMapper.java new file mode 100644 index 00000000..5bffd9fc --- /dev/null +++ b/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/mapper/BaseMapper.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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 top.continew.starter.data.mp.mapper; + +import cn.hutool.core.util.ClassUtil; +import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; +import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper; +import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; +import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper; +import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers; +import com.baomidou.mybatisplus.extension.toolkit.Db; + +import java.util.Collection; + +/** + * Mapper 基类 + * + * @param 实体类 + * @author Charles7c + * @since 1.0.0 + */ +public interface BaseMapper extends com.baomidou.mybatisplus.core.mapper.BaseMapper { + + /** + * 批量插入记录 + * + * @param entityList 实体列表 + * @return 是否成功 + */ + default boolean insertBatch(Collection entityList) { + return Db.saveBatch(entityList); + } + + /** + * 批量更新记录 + * + * @param entityList 实体列表 + * @return 是否成功 + */ + default boolean updateBatchById(Collection entityList) { + return Db.updateBatchById(entityList); + } + + /** + * 链式查询 + * + * @return QueryWrapper 的包装类 + */ + default QueryChainWrapper query() { + return ChainWrappers.queryChain(this); + } + + /** + * 链式查询(lambda 式) + * + * @return LambdaQueryWrapper 的包装类 + */ + default LambdaQueryChainWrapper lambdaQuery() { + return ChainWrappers.lambdaQueryChain(this, this.currentEntityClass()); + } + + /** + * 链式查询(lambda 式) + * + * @param entity 实体对象 + * @return LambdaQueryWrapper 的包装类 + */ + default LambdaQueryChainWrapper lambdaQuery(T entity) { + return ChainWrappers.lambdaQueryChain(this, entity); + } + + /** + * 链式更改 + * + * @return UpdateWrapper 的包装类 + */ + default UpdateChainWrapper update() { + return ChainWrappers.updateChain(this); + } + + /** + * 链式更改(lambda 式) + * + * @return LambdaUpdateWrapper 的包装类 + */ + default LambdaUpdateChainWrapper lambdaUpdate() { + return ChainWrappers.lambdaUpdateChain(this); + } + + /** + * 获取实体类 Class 对象 + * + * @return 实体类 Class 对象 + */ + default Class currentEntityClass() { + return (Class)ClassUtil.getTypeArgument(this.getClass(), 0); + } +} diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRequestMappingHandlerMapping.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRequestMappingHandlerMapping.java index 90a37d63..a0f56629 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRequestMappingHandlerMapping.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRequestMappingHandlerMapping.java @@ -25,6 +25,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.util.pattern.PathPatternParser; import top.continew.starter.core.util.ExceptionUtils; +import top.continew.starter.extension.crud.annotation.CrudApi; import top.continew.starter.extension.crud.annotation.CrudRequestMapping; import top.continew.starter.extension.crud.enums.Api; @@ -52,8 +53,9 @@ public class CrudRequestMappingHandlerMapping extends RequestMappingHandlerMappi CrudRequestMapping crudRequestMapping = handlerType.getDeclaredAnnotation(CrudRequestMapping.class); // 过滤 API,如果非本类中定义,且 API 列表中不包含,则忽略 Api[] apiArr = crudRequestMapping.api(); - Api api = ExceptionUtils.exToNull(() -> Api.valueOf(method.getName().toUpperCase())); - if (method.getDeclaringClass() != handlerType && !ArrayUtil.contains(apiArr, api)) { + CrudApi crudApi = AnnotatedElementUtils.findMergedAnnotation(method, CrudApi.class); + if (method.getDeclaringClass() != handlerType && !ArrayUtil.contains(apiArr, ExceptionUtils + .exToNull(crudApi::value))) { return null; } // 拼接路径(合并了 @RequestMapping 的部分能力) diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/controller/AbstractCrudController.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/controller/AbstractCrudController.java index de00e01e..82718bce 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/controller/AbstractCrudController.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/controller/AbstractCrudController.java @@ -146,13 +146,27 @@ public abstract class AbstractCrudController, /** * 删除 * - * @param req 删除请求参数 + * @param id ID */ @CrudApi(Api.DELETE) @Operation(summary = "删除数据", description = "删除数据") + @Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH) + @ResponseBody + @DeleteMapping("/{id}") + public void delete(@PathVariable("id") Long id) { + baseService.delete(List.of(id)); + } + + /** + * 批量删除 + * + * @param req 删除请求参数 + */ + @CrudApi(Api.BATCH_DELETE) + @Operation(summary = "批量删除数据", description = "批量删除数据") @ResponseBody @DeleteMapping - public void delete(@Validated @RequestBody IdsReq req) { + public void batchDelete(@Validated @RequestBody IdsReq req) { baseService.delete(req.getIds()); } diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java index 5b102c09..cadc2cfc 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java @@ -63,4 +63,9 @@ public enum Api { * 导出 */ EXPORT, + + /** + * 批量删除 + */ + BATCH_DELETE, } \ No newline at end of file diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/CrudServiceImpl.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/CrudServiceImpl.java index 4215f182..077a0d7c 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/CrudServiceImpl.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/CrudServiceImpl.java @@ -29,7 +29,6 @@ import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.extra.spring.SpringUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import jakarta.servlet.http.HttpServletResponse; @@ -40,6 +39,7 @@ import top.continew.starter.core.util.ClassUtils; import top.continew.starter.core.util.ReflectUtils; import top.continew.starter.core.validation.CheckUtils; import top.continew.starter.core.validation.ValidationUtils; +import top.continew.starter.data.mp.mapper.BaseMapper; import top.continew.starter.data.mp.service.impl.ServiceImpl; import top.continew.starter.data.mp.util.QueryWrapperHelper; import top.continew.starter.extension.crud.annotation.DictModel;