springboot整合Mybatis-plus框架

springboot结合Mybatis-plus实现单表增删改查整理

一、单Controller实现CRUD

思路:

  • mybatis-plus在业务层已经实现了单表的增删改查,只需要在此基础上使用泛型话处理,即可实现单表的增删改查处理
  • 通过ServiceEnums实现主体参数的封装,然后通过在Controller中通过一系列处理实现参数处理以及业务调用即实现统一处理
  • 此类处理的重点在泛型编程,只有处理好泛型编程,即可处理好单表的增删改查
1、创建BaseController实现业务表的增删改查
/**
 * 适用于单表的增删改查
 */
@RestController
@RequestMapping("/v1/mission")
public class BaseController {

    @Autowired
    private Validator validator;

    @Autowired
    private ObjectMapper mapper;

    /**
     *  查询分页
     * @param serviceName  业务名称
     * @param paramMap  查询参数
     * @return  分页结果
     * @throws JsonProcessingException
     */
    @GetMapping("/{serviceName}/page")
    public  MyPage<Object> queryPage(@PathVariable("serviceName") String serviceName,
                    @RequestParam HashMap paramMap) throws JsonProcessingException {
        ServiceEnums serviceEnum = ServiceEnums.getServiceName(serviceName);
        IService service = SpringUtil.getBean(serviceEnum.getServicename());
        Long pageNo = Optional.ofNullable(MapUtil.getLong(paramMap,"pageNo")).orElse(0L);
        Long pageSize = Optional.ofNullable(MapUtil.getLong(paramMap,"pageSize")).orElse(10L);
        IPage iPage = new Page(pageNo,pageSize);
        //携带查询参数
        if(CollUtil.isNotEmpty(paramMap)){
            Object entity =  mapper.readValue(mapper.writeValueAsString(paramMap),serviceEnum.getDomainDO());
            LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(entity);
            service.page(iPage,queryWrapper);
        }else {
            //无查询参数
            service.page(iPage);
        }
        //使用convert直接更替
        page.convert(e->BeanUtils.map(e,serviceEnum.getDomainVO()));
        //List<Object> domainDTOList = iPage.getRecords();
        //iPage.setRecords(BeanUtils.mapAsList(domainDTOList,serviceEnum.getDomainVO()));
        //IPage<Object> convert = this.page(page).convert(scheduleSectionConverter::convertDo2Vo);
        return MyPage.of(iPage);
    }

    /**
     *  查询集合
     * @param serviceName 服务名称
     * @param querMap 查询参数Map
     * @return  返回查询结果
     */
    @GetMapping(value = "/{serviceName}/list")
    public  R<List<?>> queryList(@PathVariable("serviceName") String serviceName,
             @RequestParam HashMap querMap) throws JsonProcessingException {
        ServiceEnums serviceEnum = ServiceEnums.getServiceName(serviceName);
        IService service = SpringUtil.getBean(serviceEnum.getServicename());
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
        if(CollUtil.isNotEmpty(querMap)){
            Object domainDO = mapper.readValue(mapper.writeValueAsString(querMap),serviceEnum.getDomainDO());
            queryWrapper.setEntity(domainDO);
        }
        //一页限制30个
        queryWrapper.last("limit 50");
        List<Object> resultList = service.list(queryWrapper);
        List<?> resultVOList = BeanUtils.mapAsList(resultList, serviceEnum.getDomainVO());
        return R.success(resultVOList);
    }

    /**
     * 通过ID查询对象
     * @param serviceName 业务名称
     * @param id  参数ID
     * @return  查询结果
     */
    @GetMapping(value = "/{serviceName}/get/{id}")
    public R<Object> getById(@PathVariable("serviceName") String serviceName,
                                 @PathVariable("id") Serializable id) {
        MissionErrorEnums.ARGUMENT_MUST_NOT_NULL.assertNotNull(id);
        ServiceEnums serviceEnum = ServiceEnums.getServiceName(serviceName);
        IService service = SpringUtil.getBean(serviceEnum.getServicename());
        Object domainDO = service.getById(id);
        Object domainDTO = BeanUtils.map(domainDO, serviceEnum.getDomainVO());
        return R.success(domainDTO);
    }

    /**
     * 新增数据
     * @param serviceName  业务名称
     * @param jsonParam json参数
     * @return 操作结果
     */
    @PutMapping("/{serviceName}/save")
    public R<Boolean> save(@PathVariable("serviceName") String serviceName,
                           @RequestBody String jsonParam) {
        MissionErrorEnums.ARGUMENT_MUST_NOT_NULL.assertNotEmpty(jsonParam);
        ServiceEnums serviceEnum = ServiceEnums.getServiceName(serviceName);
        IService service = SpringUtil.getBean(serviceEnum.getServicename());
        Object domainDO = this.validateAndConvert2DO(jsonParam,serviceEnum);
        return R.success(service.save(domainDO));
    }

    /**
     * 更新数据
     * @param serviceName  业务名称
     * @param jsonParam  json参数
     * @return  操作结果
     */
    @PostMapping("/{serviceName}/update")
    public R<Boolean> update(@PathVariable("serviceName") String serviceName,
                             @RequestBody String jsonParam) {
        MissionErrorEnums.ARGUMENT_MUST_NOT_NULL.assertNotEmpty(jsonParam);
        ServiceEnums serviceEnum = ServiceEnums.getServiceName(serviceName);
        IService service = SpringUtil.getBean(serviceEnum.getServicename());
        Object domainDO = this.validateAndConvert2DO(jsonParam,serviceEnum);
        return R.success(service.updateById(domainDO));
    }

    /**
     * 批量删除
     * @param serviceName  服务名称
     * @param ids   待删除ID集合
     * @return  返回结果
     */
    @DeleteMapping("/{serviceName}/batchDel")
    public R<Boolean> batchDel(@PathVariable("serviceName") String serviceName,
                              @RequestBody  List<Integer> ids) {
        MissionErrorEnums.ARGUMENT_MUST_NOT_NULL.assertNotEmpty(ids);
        ServiceEnums serviceEnum = ServiceEnums.getServiceName(serviceName);
        IService service = SpringUtil.getBean(serviceEnum.getServicename());
        return R.success(service.removeByIds(ids));
    }

    /**
     * 根据ID删除
     * @param serviceName 服务名称
     * @param id 待删除ID
     * @return 返回结果
     */
    @DeleteMapping("/{serviceName}/del/{id}")
    public R<Boolean> delById(@PathVariable("serviceName") String serviceName,
                              @PathVariable("id") Serializable id) {
        MissionErrorEnums.ARGUMENT_MUST_NOT_NULL.assertNotNull(id);
        ServiceEnums serviceEnum = ServiceEnums.getServiceName(serviceName);
        IService service = SpringUtil.getBean(serviceEnum.getServicename());
        return R.success(service.removeById(id));
    }

    /**
     * 校验并转成DO对象
     * @param jsonParam
     * @param serviceEnum
     * @return
     */
    private Object validateAndConvert2DO(String jsonParam, ServiceEnums serviceEnum) {
        //读取JSON字符串
        Object domainDTO = null;
        try {
            domainDTO = mapper.readValue(jsonParam,serviceEnum.getDomainDTO());
        } catch (JsonProcessingException e) {
            ArgumentExceptionEnum.VALID_ERROR.assertFail("无法解析json参数");
        }
        //校验参数是否正确
        Set<ConstraintViolation<Object>> validates = validator.validate(domainDTO);
        if(CollUtil.isNotEmpty(validates)){
            ConstraintViolation<Object> next = validates.iterator().next();
            ArgumentExceptionEnum.VALID_ERROR.assertFail(next.getMessage());
        }
        //将DTO参数转成DO对象
        Object domainDo = BeanUtils.map(domainDTO,serviceEnum.getDomainDO());
        return domainDo;
    }
}
2、业务枚举
  • 该类作为统筹类
  • 如果觉得比较麻烦可以采用反射的方式,不过反射方式稍微显得麻烦
@Getter
@AllArgsConstructor
public enum ServiceEnums{

    //投票对象
    TASKINFO("taskInfo","taskInfoServiceImpl",
            TaskInfoDTO.class, TaskInfoDO.class, TaskInfoVO.class),
    TASK_ITEM("taskItem","taskItemServiceImpl",
            TaskItemDTO.class, TaskItemDO.class, TaskItemVO.class),
    USER_ACCOUNT("userAccount","userAccountServiceImpl",
            UserAccountDTO.class, UserAccountDO.class, UserAccountVO.class),
    USER_INFO("userInfo","userInfoServiceImpl",
            UserInfoDTO.class, UserInfoDO.class, UserInfoVO.class),
    USER_TASK("userTask","userTaskServiceImpl",
            UserTaskDTO.class, UserTaskDO.class, UserTaskVO.class),
    WITHDRAWAL_APPLY("withdrawalApply","withdrawalApplyServiceImpl",
            WithdrawalApplyDTO.class, WithdrawalApplyDO.class, WithdrawalApplyVO.class),
    WITHDRAWAL_RECORD("withdrawalRecord","withdrawalRecordServiceImpl",
            WithdrawalRecordDTO.class, WithdrawalRecordDO.class, WithdrawalRecordVO.class),
    ;


    /**
     * 服务模块名
     */
    private String service;

    /**
     * 服务名称
     */
    private String servicename;

    /**
     * 领域对象名称
     */
    private Class<?> domainDTO;

    /**
     * 数据操作对象
     */
    private Class<?> domainDO;

    /**
     * 值对象
     */
    private Class<?> domainVO;


    public static ServiceEnums getServiceName(String service){
        ServiceEnums[] values = ServiceEnums.values();
        for (ServiceEnums serviceEnum:values){
            if(serviceEnum.getService().equals(service)){
                return serviceEnum;
            }
        }
        MissionErrorEnums.SERVICE_NAME_NOT_DEFINE.assertFail(service);
        return null;
    }
}
二、Mybatis-plus抽象简化连表查询

思路:

  • 连表查询的关键在于查询条件的构建,因此第一步是在查询条件上下功夫
1、创建WrapperHelper工具类
public class WrapperHelper {

    public static  <T> T queryOne( DoubleArg doubleArg){
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(doubleArg.getFunction(),doubleArg.getValue());
        queryWrapper.eq(doubleArg.getFunction2(),doubleArg.getValue2());
        queryWrapper.last("limit 1");
        IService service = SpringUtil.getBean(doubleArg.getIService().getClass());
        T one = (T)service.getOne(queryWrapper);
        return one;
    }

    public static  <T> T queryOne(SingleArg singleArg){
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(singleArg.getFunction(),singleArg.getValue());
        queryWrapper.last("limit 1");
        IService service = SpringUtil.getBean(singleArg.getIService().getClass());
        T one = (T)service.getOne(queryWrapper);
        return one;
    }

    public static  <T> T queryOne(IService clazz, SFunction sFunction,Object value){
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(sFunction,value);
        queryWrapper.last("limit 1");
        IService service = SpringUtil.getBean(clazz.getClass());
        return  (T)service.getOne(queryWrapper);
    }

    public static  <T> List<T> queryList(IService clazz, SFunction sFunction, Object value){
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(sFunction,value);
        IService service = SpringUtil.getBean(clazz.getClass());
        return  (List<T>)service.list(queryWrapper);
    }

    public static  <T> List<T> queryList(DoubleArg doubleArg){
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(doubleArg.getFunction(),doubleArg.getValue());
        queryWrapper.eq(doubleArg.getFunction2(),doubleArg.getValue2());
        IService service = SpringUtil.getBean(doubleArg.getIService().getClass());
        return  service.list(queryWrapper);
    }

    public static <T> List<T> queryInList(IService clazz, SFunction sFunction, Object value) {
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(sFunction,value);
        IService service = SpringUtil.getBean(clazz.getClass());
        return  service.list(queryWrapper);

    }

    public static <T>Page<T> queryPage(PageArg pageArg){
        Page page = new Page(pageArg.getPageNo(),pageArg.getPageSize());
        IService service = SpringUtil.getBean(pageArg.getIService().getClass());
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(pageArg.getFunction(),pageArg.getValue());
        if(null != pageArg.getOrderColumn()){
            queryWrapper.orderByDesc(pageArg.getOrderColumn());
        }
        queryWrapper.orderByDesc();
        service.page(page);
        return page;
    }

}
2、查询条件封装
@Data
@AllArgsConstructor
@NoArgsConstructor
public  class SingleArg<T>{

    /**对应Service*/
    private IService<T> iService;
    /**调用字段*/
    private SFunction<T,?> function;
    /**参数值*/
    private Object value;
}
//==============================
@Data
@AllArgsConstructor
@NoArgsConstructor
public  class DoubleArg<T> extends SingleArg{

    private SFunction<T,?> function2;

    private Object value2;

    public  DoubleArg(IService service, SFunction<T,?> function, Object value, SFunction<T,?> function2, Object value2){
      super(service,function,value);
      this.function2 =function2;
      this.value2 = value2;
    }
}
3、关键表外键整理
public class TableFiledFunctions {

    //UserAccount外键user_id
    public static final SFunction<UserAccountDO,?> userAccount_UserId = UserAccountDO::getUserId;

    //TaskInfo外键itemId
    public static final SFunction<TaskInfoDO,?> taskInfo_itemId = TaskInfoDO::getItemId;

}
4、一对一连表查询
//封装1对1的参数
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDetailVO {

    private UserInfoDO userInfoDO;

    private UserAccountDO userAccountDO;

}

//实现查询
@Slf4j
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfoDO> implements UserInfoService {

    @Resource
    private UserAccountService userAccountService;

    @Override
    public  UserDetailVO getUserDetail(Long userId){
        //第一种方式:直接传递参数
       UserAccountDO userAccountDO = WrapperHelper.queryOne(userAccountService,
                TableFiledFunctions.userAccount_UserId,userId);
        //第二种方式
        SFunction<UserAccountDO,?> userAccount_UserId = UserAccountDO::getUserId;
        SingleArg singleArg = new SingleArg(userAccountService,userAccount_UserId,userId);
        UserAccountDO userAccountDO2 = WrapperHelper.queryOne(singleArg);
        //最后封装成返回
        return new UserDetailVO(getById(userId),userAccountDO);
    }

}
5、一对多连表查询
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TaskItemDetailVO {

    private TaskItemDO taskItemDO;

    private List<TaskInfoDO>  taskInfoDOList;
}

@Slf4j
@Service
public class TaskItemServiceImpl extends ServiceImpl<TaskItemMapper, TaskItemDO> implements TaskItemService {

    @Lazy
    @Resource
    private TaskInfoService taskInfoService;

    @Override
    public TaskItemDetailVO getTaskItemDetailVO(Integer taskItemId) {
        List<TaskInfoDO> taskInfoList = WrapperHelper.queryList(taskInfoService, TableFiledFunctions.taskInfo_itemId,taskItemId);
        return  new TaskItemDetailVO(getById(taskItemId), taskInfoList);
    }
}
6、多对多连表查询
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserTaskListVO {

    /**
     * 用户信息
     */
    private UserInfoDO userInfo;
    /**
     * 用户的任务信息
     */
    private List<UserTaskDetailVO>  userTaskList;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserTaskDetailVO {

    /**
     * 用户任务信息
     */
    private UserTaskDO userTaskDO;

    /**
     * 任务明细信息
     */
    private TaskInfoDO taskInfoDO;
}
@Slf4j
@Service
public class UserTaskServiceImpl extends ServiceImpl<UserTaskMapper, UserTaskDO> implements UserTaskService {

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private TaskInfoService taskInfoService;

    @Override
    public UserTaskListVO getUserTaskList(UserTaskQueryDTO userTaskQueryDTO) {
        //查询用户信息
        UserInfoDO userInfo = userInfoService.getById(userTaskQueryDTO.getUserId());

        //分页查询用户任务信息
        Page page = new Page(userTaskQueryDTO.getPageNo(),userTaskQueryDTO.getPageSize());
        this.page(page);
        List<UserTaskDO> records = page.getRecords();

        //查询任务集合
        List<Integer> userTaskIds = records.stream().map(UserTaskDO::getTaskId).collect(Collectors.toList());
        List<TaskInfoDO> taskInfoDOS = taskInfoService.listByIds(userTaskIds);
        Map<Integer, TaskInfoDO> taskInfoMap = taskInfoDOS.stream().
            collect(Collectors.toMap(TaskInfoDO::getId, e -> e));

        List<UserTaskDetailVO> detailList = Lists.newArrayListWithCapacity(records.size());

        records.forEach(e->{
            detailList.add(new UserTaskDetailVO(e,taskInfoMap.get(e.getTaskId())));
        });
        //查询任务详情
        page.setRecords(detailList);
        return new UserTaskListVO(userInfo,page);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值