多条件模糊分页查询(angular+primeng+springboot)

本文介绍了如何在Angular+Primeng应用中结合SpringBoot实现多条件模糊分页查询。作者在后端创建了一个新的实体类,结合PageHelper和Lombok进行分页处理。在前端,利用组件间通信解决分页数据的实时渲染问题。通过监听表单提交和数据变更,实现实时更新表格。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实现了分页查询后,我原本的项目之前的模糊查询失效,之前是传一个封装好的实体对象给后端,后端通过这个对象查询后返回结果给到前端。由于实现了分页,所以查询得到的结果也需要分页。

有个很关键的问题是分页需要传pageNumpageSize这两个参数,后端@RequestBody一次只能接收一个对象(@RequestBody是读取的流的方式, 在取 body参数时第一个参数取到后把request.getInputStream()关闭,一个请求中只包含一个request body)。而我要进行的查询又需要传一个对象,在走了一些弯路后想到:为什么不把pageNum和pageSize以及需要的实体整合成一个新的对象,传给后端后再分开获取值呢?这样虽然比较麻烦,但是没有其他思路我就这么试了,确实可以实现想要的多条件分页模糊查询。

后端实现

**注意:**要先导入PageHelper和Lombok插件,具体操作可以查看我的上一篇博客。

  1. 新建一个实体类

    @Data
    @NoArgsConstructor
    public class FundPage {
        private String fundCode;
        private String fundFullName;
        private String custodianCode;
        private String fundCategory;
        private String needReview;
        private Integer pageNum;
        private Integer pageSize;
    }
    
  2. dao层和mapper文件不需要更改,修改service层和实现类的业务函数

    //原本的service层函数
    List<FundInfo> getLots(FundInfo fundInfo)
    //改写后
    PageInfo<FundInfo> getLots(FundInfo fundInfo,Integer pageNum,Integer pageSize);
    //service的实现类
    @Override
        public PageInfo<FundInfo> getLots(FundInfo fundInfo,Integer pageNum,Integer pageSize) {
            FundInfoExample example = new FundInfoExample();
            FundInfoExample.Criteria criteria = example.createCriteria();
            if (fundInfo.getFundCode() != null) {
                criteria.andFundCodeLike("%" + fundInfo.getFundCode() + "%");
            }
            if (fundInfo.getCustodianCode() != null) {
                criteria.andCustodianCodeLike("%" + fundInfo.getCustodianCode() + "%");
            }
            if (fundInfo.getFundFullName() != null) {
                criteria.andFundFullNameLike("%" + fundInfo.getFundFullName() + "%");
            }
            if (fundInfo.getNeedReview() != null) {
                criteria.andNeedReviewLike("%" + fundInfo.getNeedReview() + "%");
            }
            if (fundInfo.getFundCategory() != null) {
                criteria.andFundCategoryLike("%" + fundInfo.getFundCategory() + "%");
            }
            PageHelper.startPage(pageNum,pageSize);
            List<FundInfo> fundInfoList=fundInfoMapper.selectByExample(example);
            PageInfo<FundInfo> pageInfo=new PageInfo<>(fundInfoList);
            return pageInfo;
        }
    

    这里使用了PageHelper中的PageInfo类,这里主要是用到了其中的几个方法。

    注意:PageHelper.startPage(pageNum,pageSize);的作用开启分页,通过将查询后的结果集用PageInfo型的对象接收即可实现分页。此外,这里的模糊查询使用的是逆向工程生成的方法,具体可以查看我的其他博客。

  3. controller层

    @Autowired
        private FundInfoService fundInfoService;
    ...
    @PostMapping("/test")
        public Result<List<FundInfo>> getTest(@RequestBody FundPage fundPage){
            FundInfo fundInfo=new FundInfo();
            fundInfo.setNeedReview(fundPage.getNeedReview());
            fundInfo.setFundCategory(fundPage.getFundCategory());
            fundInfo.setFundCode(fundPage.getFundCode());
            fundInfo.setFundFullName(fundPage.getFundFullName());
            fundInfo.setCustodianCode(fundPage.getCustodianCode());
            int pageNum=fundPage.getPageNum();
            int pageSize=fundPage.getPageSize();
            PageInfo<FundInfo> pageInfo=fundInfoService.getLots(fundInfo,pageNum,pageSize);
            List<FundInfo> fundInfoList=pageInfo.getList();
            int total= Math.toIntExact(pageInfo.getTotal());
            return Result.buildResult(Result.Status.OK,fundInfoList,total);
        }
    

    controller层通过对获取到的FundPage的属性进行提取,提取到的fundInfo,pageNum,pageSize作为调用模糊查询方法的参数。查询结果用PageInfo类型的对象接收,再定义一个FundInfo类型的List集合,调用PageInfogetList()方法,最后通过工具类返回给前端。

前端实现

由于我是使用angular+primeng的来做前端,所以这里贴上我的页面布局,上面的部分是一个组件,下面的部分是一个组件(angular是组件化开发,可以理解为一个页面/部分是一个组件)

由于模糊查询提交的表单是在一个组件,显示结果在另一个组件,所以当中涉及到组件间传值的问题

image-20210119143124488

  1. 我解决组件间传值的方法是在fundInfoTable组件中导入fundInfo组件,然后再ngDoCheck()函数中监听表单是否提交

    ngDoCheck()是组件的生命周期的其中一部分,用于监测数据是否变更,但是每个变化检测周期都会大频率调用这个钩子,所以要轻量级实现,以下是官方文档的部分介绍

    image-20210119143611851

  2. 新建一个实体类,这实体类与后端是一致的。

    export class FundPage {
        fundCode: string;
        fundFullName: string;
        fundCategory: string;
        custodianCode: string;
        needReview: string;
        pageNum:number;
        pageSize:number;
    }
    
  3. 将提交后的表单数据赋值给fundPage,并把pageNum和pageSize给个初始化值(null也行)

    sub(data) {
        if (data.custodianCode == '') {
          data.custodianCode = null;
        }
        if (data.fundCategory == '') {
          data.fundCategory = null;
        }
        if (data.needReview == '') {
          data.needReview = null;
        }
        this.fundPage=data;
        this.fundPage.pageNum=1;
        this.fundPage.pageSize=10;
      }
    

    这里省略了表单还有其他细节,主要也是说一个思路

  4. fundInfoTable组件定义监听变量

    //前两个用于控制懒加载的函数在ngDoCheck()中只被调用一次,没有控制的话会一直调用
    bindOne: boolean = false;
    bindTwo: boolean = true;
    //用于区别对全部数据的分页查询和对模糊条件的分页查询
    isSearch: boolean = false;
    
  5. 编写ngDoCheck()变更检测钩子

    ngDoCheck() {
        //当监听到查询值改变时,将监听值bindTwo赋值为true,使页面能够再次重新调用懒加载函数
        if(this.fundPage!=this.fundInfoComponent.fundPage){
          this.bindTwo=true;
        }
        // 检查是否提交了模糊查询服务
        //通过两个变量来监听,使得this.loadFundInfos()只能调用一次
        if (this.fundInfoComponent.fundPage&&(this.bindOne||this.bindTwo)) {
          this.fundPage = this.fundInfoComponent.fundPage;
          this.isSearch = true;
          this.bindTwo=false;
          this.loadFundInfos();
          //查询后回到第一页
          this.first=0
        }
      }
    
  6. 懒加载函数

    //懒加载分页的数据
      loadFundInfos() {
        this.loading = true;
        setTimeout(() => {
          if (this.isSearch) {
            this.fundPage.pageNum = (this.first + 10) / 10;
            this.fundPage.pageSize = this.rows;
            this.fundService.getLots(this.fundPage)
              .then(response => { this.totalRecords = response.total; this.infos = response.data; })
          } else {
            this.fundService.getPage(this.first + 10, this.rows)
              .then(response => { this.totalRecords = response.total; this.infos = response.data; })
          }
          this.loading = false;
        }, 500)
      }
    

总结

后端的模糊查询分页其实难度不大,主要是前端卡了很久,主要问题在于如何把查询到的分页数据实时渲染到table上,试了几种钩子都没有效果,最后是突然想到之前做过的一道算法题,给我提供了用两个监听变量来控制函数的调用。我的实现方法可能不规范,但总归是实现了,希望能给大家一些思路,我是个新手,如果有错误的地方,欢迎大家指正,我们可以一起讨论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值