千家信息网

JPA怎么通过Specification实现复杂查询

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,小编给大家分享一下JPA怎么通过Specification实现复杂查询,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!JPA 通过Specification实现复杂查询JPA中继承Ba
千家信息网最后更新 2025年01月19日JPA怎么通过Specification实现复杂查询

小编给大家分享一下JPA怎么通过Specification实现复杂查询,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

    JPA 通过Specification实现复杂查询

    JPA中继承BaseRepo之后,可以使用最基本的增删改查,如果想实现复杂查询,则需要借助Specification来完成这个功能:

    下面就简单介绍一下Specification的使用

    public void findAll(ConstructPlanPageReqEntity constructPlanPageReqEntity) {        Integer pageNum = page.getPageNum();        Integer pageSize = page.getPageSize();        String costType = constructPlanPageReqEntity.getCostType();        String name = constructPlanPageReqEntity.getName();        String planMoneyStart = constructPlanPageReqEntity.getPlanMoneyStart();        String planMoneyEnd = constructPlanPageReqEntity.getPlanMoneyEnd();        String singMoneyEnd = constructPlanPageReqEntity.getSingMoneyEnd();        String signMoneyStart = constructPlanPageReqEntity.getSignMoneyStart();        long projectId = Long.parseLong(constructPlanPageReqEntity.getProjectId());        String status = constructPlanPageReqEntity.getStatus();        //分页        pageNum=pageNum-1;        Pageable pageable = PageRequest.of(pageNum, pageSize);//多条件匹配查询        Specification specification= new Specification() {            @Override            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {                ArrayList list = new ArrayList<>();                Path costType1 = root.get("costType");                Path name1 = root.get("name");                Path projectId1 = root.get("projectId");                Path status1 = root.get("status");                if (projectId>0){                    list.add(criteriaBuilder.equal(projectId1,projectId));                }                if (StringUtil.isNotEmpty(status)){                    list.add(criteriaBuilder.equal(status1,status));                }                //条件查询                if (StringUtil.isNotEmpty(costType)){                    list.add(criteriaBuilder.equal(costType1,costType));                }                //模糊查询                if (StringUtil.isNotEmpty(name)){                    list.add(criteriaBuilder.like(name1,"%"+name+"%"));                }                //范围查询                if (StringUtil.isNotEmpty(planMoneyStart)&&StringUtil.isNotEmpty(planMoneyEnd)){                    try {                        list.add(criteriaBuilder.between(root.get("planMoney"),NumberUtil.strToDouble(planMoneyStart),NumberUtil.strToDouble(planMoneyEnd)));                    } catch (Exception e) {                        throw new ApiException("规划金额查询失败");                    }                }                 //排序                criteriaQuery.orderBy(criteriaBuilder.asc(root.get("name")));                Predicate[] array = new Predicate[list.size()];                return criteriaBuilder.and(list.toArray(array));            }        };}

    以上代码实现了多条件查询,其中需要重写toPredicate方法,具体参数:

    • 用root.get()获取bean中的数据库对应字段

    • 用criteriaBuilder来组建条件查询语句

    上图是criteriaBuilder各种sql符号的方法名,根据需求组建不同的sql语句

    criteriaBuilder.and(list.toArray(array))这句是最后定义各个sql查询条件的关系,这里用的and

    至此,复杂sql语句就拼接完成,本人对Specification的使用未进行深入研究,个人觉得相对filter Strem的复杂查询来说Specification更繁琐,因此更倾向于通过Strem的复杂查询,这回就不多说了,下次就介绍下如何使用Stream进行复杂查询

    spring-data-jpa Specification拼接复杂查询

      public Page findAll(Map params, ServiceItemConsumeStatus serviceItemConsumeStatus,ServiceItemStatus serviceItemStatus, Pageable pageable) {        return dao.findAll(spec(serviceItemConsumeStatus, serviceItemStatus, params), pageable);    }    private Specification spec(final ServiceItemConsumeStatus serviceItemConsumeStatus,     final ServiceItemStatus serviceItemStatus, Map params) {        Collection filters = SearchFilter.parse(params).values();        final Specification fsp = SearchFilter.spec(filters, ServiceItem.class);        Specification sp = new Specification() {            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {                Predicate pred = fsp.toPredicate(root, query, cb);                if (ServiceItemConsumeStatus.可消费.equals(serviceItemConsumeStatus)) {                    pred = cb.and(pred, cb.gt(root.get("countLeft").as(int.class), 0));                } else if (ServiceItemConsumeStatus.消费完毕.equals(serviceItemConsumeStatus)) {                    pred = cb.and(pred, cb.le(root.get("countLeft").as(int.class), 0));                }                if (serviceItemStatus != null) {                    pred = cb.and(pred, cb.equal(root.get("status"), serviceItemStatus));                }                return pred;            }        };        return sp;    }

    看完了这篇文章,相信你对"JPA怎么通过Specification实现复杂查询"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

    查询 复杂 条件 语句 方法 篇文章 消费 不同 繁琐 上图 个人 代码 倾向 功能 参数 字段 完了 数据 数据库 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发承揽合同 保定地区软件开发公司电话 数据库不包含多个数据语句 为赌博提供网络技术支持判决 域控服务器 日语 软件开发如何进行质量保证 蚂蚁字节互联网科技有限公司 苏州市软件开发平均工资 服务器管理口日志获取 免费又好玩的我的世界服务器 结信网络技术服务上海公司 湖北统一软件开发价格监测中心 ke2050怎么使用数据库 服务器站点管理工具 株洲网络安全保障费用多少 软件开发中的图 成都 oa软件开发 企业软件开发adbp语言 兰州服务器优化 华为软件开发工程师田维兵 广州快修网络技术 服务器如何下载离线安装包 关于生活离不开科技与互联网 农行软件开发中心西安部地址 校园网络安全书籍 网络安全卓越人才计划考试 城阳区微信小程序软件开发哪家好 北京潜度网络技术有限公司 我的世界网易服务器手机和电脑 金蝶提示网络加密服务器
    0