Controller封装基础的增删改查BaseController,简化单表业务

背景

配置代码生成器生成出controller、service、mapper,虽然大部分开源框架service与mapper都生成好了,但是controller中还遗留冗余代码,我的想法是能不能把基本的单表CRUD抽出来,提供一个公共的Controller控制器。
利用java语言的特性可以实现,也会存在一些问题。

实现思路

  • 创建父控制器BaseController
  • 一个Model(表实体Model)对应一个service,service作为泛型为BaseController的属性
  • 通过注入的方式注入service属性(表不可能重复,因此service不存在重复注入Spring容器)
  • 提取增删改查Mapping

service接口需要提供通用增删改查接口,对持久层框架没有限制

具体步骤

我是用的是mybatis-plus框架,service泛型需要继承自IService接口,这个接口是MybatisPlus提供的公共service层接口,基本的增删改查方法接口已经提供好了,需要传递一个Model泛型

public abstract class BaseController<S extends IService<M>, M> {

    @Autowired
    protected S service;
	
}

接着提取出公共的增删改查Mapping

public abstract class BaseController<S extends IService<M>, M extends BaseModel> {

    @Autowired
    protected S service;

    @ResponseBody
    @GetMapping("/baseQueryById/{id}")
    @ApiOperation(value = "基础功能-通过ID查询单条记录", notes = "基础功能-通过ID查询单条记录", httpMethod = "GET", response = Result.class)
    @ApiOperationSupport(order = 1)
    protected Result baseQueryById(@PathVariable("id") Long id) {
        if (ObjectUtil.isNull(id) || id <= 0L) {
            return Result.fail("id不能为空!");
        }
        M m = service.getById(id);
        return Result.success(m);
    }

    @ResponseBody
    @PostMapping("/baseQueryByParam")
    @ApiOperation(value = "基础功能-条件查询", httpMethod = "POST", response = Result.class)
    @ApiOperationSupport(order = 2)
    protected Result baseQueryByParam(@RequestBody(required = false) M param) {
        if (ObjectUtil.isNull(param)) {
            param = service.modelInstance();
        }
        List<M> list = service.listByParam(param);
        return Result.success(list);
    }

    @ResponseBody
    @PostMapping("/baseQueryPageByParam")
    @ApiOperation(value = "基础功能-条件查询分页", httpMethod = "POST", response = Result.class)
    @ApiOperationSupport(order = 3)
    protected Result baseQueryPageByParam(@RequestBody(required = false) M param) {
        if (ObjectUtil.isNull(param)) {
            param = service.modelInstance();
        }
        IPage<M> page = PageUtil.pageBean(param);
        return Result.success(service.listPageByParam(page, param));
    }

    @Log(title = "基础新增")
    @ResponseBody
    @PostMapping("/baseAdd")
    @ApiOperation(value = "基础功能-新增", httpMethod = "POST", response = Result.class)
    @ApiOperationSupport(order = 4)
    protected <DTO> Result baseAdd(@RequestBody DTO m) {
        M param = JSON.parseObject(JSON.toJSONString(m), service.getModelClass());
        if (!service.save(param)) {
            return Result.fail(ResultEnum.FAIL_INSERT);
        }
        return Result.success(ResultEnum.SUCCESS_INSERT);
    }

    @Log(title = "基础编辑")
    @ResponseBody
    @PutMapping("/baseEdit")
    @ApiOperation(value = "基础功能-修改", httpMethod = "PUT", response = Result.class)
    @ApiOperationSupport(order = 5)
    protected <DTO> Result baseEdit(@RequestBody @Validated(value = {Update.class}) DTO m) {
        M param = JSON.parseObject(JSON.toJSONString(m), service.getModelClass());
        if (!service.updateById(param)) {
            return Result.fail(ResultEnum.FAIL_UPDATE);
        }
        return Result.success(ResultEnum.SUCCESS_UPDATE);
    }

    @Log(title = "基础删除")
    @ResponseBody
    @DeleteMapping("/baseDeleteByIds/{ids}")
    @ApiOperation(value = "基础功能-根据主键id删除(多个id根据,分隔)", httpMethod = "DELETE", response = Result.class)
    @ApiOperationSupport(order = 6)
    protected Result baseDeleteByIds(@PathVariable("ids") String ids) {
        if (StrUtil.isEmpty(ids)) {
            return Result.fail("删除条件id不能为空");
        }
        String[] idsArr = ids.split(StringPool.COMMA);
        if (idsArr.length > 1000) {
            return Result.fail("不能批量删除超过1000个数据");
        }
        List<Long> idList = StringUtils.splitToList(ids, Long::valueOf);
        if (service.removeByIds(idList)) {
            return Result.success(ResultEnum.SUCCESS_DELETE);
        }
        return Result.success(ResultEnum.FAIL_DELETE);
    }
	
}

其中Result为公共的返回实体,Log是我在项目中封装的日志注解,还用到了SwaggerUi接口文档框架

遇到的问题

1、引入swaggerUi后,接口文档的请求参数不能友好的定制化设置,如下图

图片.png

参数因为是泛型,不好定制化处理,必须重写BaseController的方法,然后重新再方法中添加swaggerUI注解

2、如果需要扩展参数进行crud,必须重写父类BaseController中的方法,并且如果是扩展类型(DTO,VO)需要进行一次转换,不过这种转换的效率应该可以忽略不计

    // 项目中的代码片段
    @Log(title = "字典类型新增")
    @Override
    protected <DTO> Result baseAdd(@RequestBody DTO m) {
        BaseDictTypeModel param = MapperUtil.convert(m, BaseDictTypeModel.class);
        return Result.successBoolean(service.insertByParam(param));
    }

重写注意要添加@RequestBody注解

总结

实际开发过程中并没有想象中的那么简化代码,但是提供了一个规则,使代码编写思路变的清晰,也减少了单表业务的代码量

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值