千家信息网

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

发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,小编给大家分享一下JPA怎么通过Specification实现复杂查询,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!JPA 通过Specification实现复杂查询JPA中继承Ba
千家信息网最后更新 2024年11月28日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安全错误 数据库的锁怎样保障安全 冒险岛079服务器进不了 狭义的网络安全是指 威龙服务器机柜 懂网络技术创业 liunx服务器怎么连ftp 数据库增加用户的命令 网络安全隐患和防范措施教案设计 我的世界1.8x服务器 计算机网络技术轨道交通方向 佛山数字软件开发费用 眼镜行业软件开发哪家比较专业 电脑服务器超时请稍后再试 群晖nas搭建免流服务器 前端页面提交数据到数据库 dayz服务器管理器 智能综合安防管理平台服务器 tvs4000电视墙服务器配置 药品中标信息数据库 如何搭建电脑服务器ip 苏州服务器内部线 上海品牌网络技术信息中心 华为路由器设置时找不到服务器 公司服务器能看到密码 水务局网络安全自查报告 重庆渝中区互联网科技有限公司 大连市委网络安全与信息化 江西机电软件开发要多少钱 大学生网络安全保卫个人工作 安生 网络安全 学校服务器是自己搭建还是租用
    0