1 需求

对于数据的增删改查,一般都是先查询一个list,然后进行查询、编辑或删除操作,list的查询一般采用分页查询。

我们经常需要动态的根据前端上送的查询条件,过滤筛选出指定的结果,如下图所示,本例需要根据服务编号、服务名称、框架版本作为条件进行查询:

分页查询

 

2 理论

2.1 框架

本例中前端采用基于element-ui的vue框架,后端框架采用springboot+mybatis-plus。

2.2 原理

借助于mybatis-plus的条件构造器,构造基于java bean的条件查询,因为需要上送分页数据,因此controller中采用Map接收传入参数。

  1. 前端通过REST接口发送请求到后端,带查询条件;
  2. 后端通过org.apache.commons.beanutils.BeanUtils将Map转换为Java Bean
  3. 通过QueryWrapper创建构造器,传入上面获得的Java Bean;
  4. 返回分页查询结果

 

3 实现

 

3.1 前端实现

通过getDataList发送请求到后端获取分页结果,核心实现代码如下:

// 获取数据列表
      getDataList () {
        this.dataListLoading = true
        this.$http({
          url: this.$http.adornUrl('/v1/srv/serviceinfo/list'),
          method: 'get',
          params: this.$http.adornParams({
            'page': this.pageIndex,
            'limit': this.pageSize,
            'serviceCd': this.dataForm.serviceCd !== '' ? this.dataForm.serviceCd : null,
            'serviceName': this.dataForm.serviceName !== '' ? this.dataForm.serviceName : null,
            'serviceVersionCd': this.dataForm.serviceVersionCd !== '' ? this.dataForm.serviceVersionCd : null
          })
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.dataList = data.page.list
            this.totalPage = data.page.totalCount
          } else {
            this.dataList = []
            this.totalPage = 0
          }
          this.dataListLoading = false
        })
      }

3.2 后端实现

通过controller接收Map参数params,调用querPageForObj进行条件查询,核心代码如下:

/** 
     * {@inheritDoc}
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     */
    @Override
    public PageUtils querPageForObj(Map<String, Object> params){
        ServiceInfo serviceInfo = new ServiceInfo();
        try {
            BeanUtils.populate(serviceInfo, params);
        } catch (IllegalAccessException e) {
            log.error("convert params Map to Object error, e=", e);
            throw new BizException("参数类型转换错误IllegalAccessException");
        } catch (InvocationTargetException e) {
            log.error("convert params Map to Object error, e=", e);
            throw new BizException("参数类型转换错误InvocationTargetException");
        }
        IPage<ServiceInfo> page = this.page(
                new Query<ServiceInfo>().getPage(params),
                new QueryWrapper<ServiceInfo>(serviceInfo)
        );
        return new PageUtils(page);
    }

4 踩坑

在使用mybatis-plus的条件构造器时,只要出入的java bean不为null,都会被作为条件进行查询,且使用BeanUtils进行转换时也是以null作为条件。

但是我们实际的需求是:只要参数中内容为空即表示不参与查询

后面通过尝试,在前端提交参数时进行了简单改造,有条件则上送,无条件则不上送。

改造前代码:

params: this.$http.adornParams({
            'page': this.pageIndex,
            'limit': this.pageSize,
            'serviceCd': this.dataForm.serviceCd,
            'serviceName': this.dataForm.serviceName,
            'serviceVersionCd': this.dataForm.serviceVersionCd
          })

改造后代码:

params: this.$http.adornParams({
            'page': this.pageIndex,
            'limit': this.pageSize,
            'serviceCd': this.dataForm.serviceCd !== '' ? this.dataForm.serviceCd : null,
            'serviceName': this.dataForm.serviceName !== '' ? this.dataForm.serviceName : null,
            'serviceVersionCd': this.dataForm.serviceVersionCd !== '' ? this.dataForm.serviceVersionCd : null
          })

这样后端在接收到的Map中只会出现作为查询条件的字段,转换后的java bean也是如此,这样mybatis-plus的Wrapper查询构造器就能正常处理。

5 参考

element-ui资料:https://element.eleme.cn/#/zh-CN

mybatis-plus资料:https://mybatis.plus/

 

Logo

前往低代码交流专区

更多推荐