将Hibernate条件查询转换为JPA条件查询,包括子查询

时间:2019-07-24 04:42:11

标签: java persistence hibernate-criteria criteria-api jpa-criteria

我正在尝试将休眠条件转换为jpa条件。我能够成功地将其转换为简单查询,但无法对包含子查询的查询进行转换。查询已生成,但未添加where子句中的限制。我在下面提供了旧代码(休眠标准)和新编写的代码(jpa标准)

我想使用jpa条件api构建动态查询。动态查询使用子查询。

//旧版代码

Criteria criteria = getSession().createCriteria(SecurityUsers.class, "user");
        criteria.add(Restrictions.eq("type", 0L));
        if (dto.getUserId() != null && !"".equals(dto.getUserId())) 
            criteria.add(Restrictions.like("name", "%" + dto.getUserId().trim().toUpperCase() + "%"));
        if (dto.getUserStatus() != null && !"".equals(dto.getUserStatus())) 
            criteria.add(Restrictions.eq("activeFlag", dto.getUserStatus().trim()));
        if (dto.getUserType() != null && !"".equals(dto.getUserType())) 
            criteria.add(Restrictions.eq("userAgency", dto.getUserType().trim()));

        if ((dto.getFirstName() != null && !"".equals(dto.getFirstName())) ||
              (dto.getLastName() != null && !"".equals(dto.getLastName())) ||
              (dto.getState() != null && !"".equals(dto.getState()))) {
            DetachedCriteria personCriteria = DetachedCriteria.forClass(Person.class, "person");
            personCriteria.add(Property.forName("person.personId").eqProperty("user.personId"));
            personCriteria.setProjection(Property.forName("personId"));

            if (dto.getFirstName() != null && !"".equals(dto.getFirstName())) 
                personCriteria.add(Restrictions.like("firstName", "%" + dto.getFirstName() + "%"));
            if (dto.getLastName() != null && !"".equals(dto.getLastName())) 
                personCriteria.add(Restrictions.like("lastName", "%" + dto.getLastName() + "%"));
            criteria.add(Subqueries.exists(personCriteria));

            if (dto.getState() != null && !"".equals(dto.getState())) {
                DetachedCriteria addressCriteria = DetachedCriteria.forClass(Address.class, "address");
                addressCriteria.add(Property.forName("person.addressId").eqProperty("address.addressId"));
                addressCriteria.setProjection(Property.forName("addressId"));
                addressCriteria.add(Restrictions.eq("state", dto.getState()));
                personCriteria.add(Subqueries.exists(addressCriteria));
            }
        }
        if (dto.getUserGroups() != null && !"".equals(dto.getUserGroups())) {
            String[] userGroups = Utilities.getStringArray(dto.getUserGroups(), ",");
            DetachedCriteria userGroupsCriteria = DetachedCriteria.forClass(SecurityGroupings.class, "groups");
            userGroupsCriteria.add(Property.forName("user.name").eqProperty("groups.id.securityUsers_1.name"));
            userGroupsCriteria.setProjection(Property.forName("id"));
            userGroupsCriteria.add(Restrictions.in("groups.id.securityUsers.name", userGroups));
            criteria.add(Subqueries.exists(userGroupsCriteria));
        }

// my jpa criteria code

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<SecurityUsers> q = cb.createQuery(SecurityUsers.class);
        Root<SecurityUsers> root = q.from(SecurityUsers.class);
        q.select(root);

        List<Predicate> predicates = new ArrayList<>();

        predicates.add((Predicate) cb.equal(root.<String>get("type"), 0L));
        if (dto.getUserId() != null && !"".equals(dto.getUserId())) {
            predicates.add(
                    (Predicate) cb.like(root.<String>get("name"), "%" + dto.getUserId().trim().toUpperCase() + "%"));
        }
        if (dto.getUserStatus() != null && !"".equals(dto.getUserStatus())) {
            predicates.add((Predicate) cb.equal(root.<String>get("activeFlag"), dto.getUserStatus().trim()));
        }
        if (dto.getUserType() != null && !"".equals(dto.getUserType())) {
            predicates.add((Predicate) cb.equal(root.<String>get("userAgency"), dto.getUserType().trim()));
        }
        Predicate[] p0 = predicates.toArray(new Predicate[predicates.size()]);
        q.where(cb.and((javax.persistence.criteria.Predicate[]) p0));

        if ((dto.getFirstName() != null && !"".equals(dto.getFirstName()))
                || (dto.getLastName() != null && !"".equals(dto.getLastName()))
                || (dto.getState() != null && !"".equals(dto.getState()))) {

            Subquery<Person> personSubquery = q.subquery(Person.class);
            Root<Person> personInfo = personSubquery.from(Person.class);
            List<Predicate> personPredicates = new ArrayList<>();
            personSubquery.select(personInfo.get("personId"));
            personPredicates.add(cb.equal(personInfo.<String>get("personId"), root.<String>get("personId")));
            if (dto.getFirstName() != null && !"".equals(dto.getFirstName())) {
                personPredicates
                        .add((Predicate) cb.like(root.<String>get("firstName"), "%" + dto.getFirstName() + "%"));
            }
            if (dto.getLastName() != null && !"".equals(dto.getLastName())) {
                personPredicates.add((Predicate) cb.like(root.<String>get("lastName"), "%" + dto.getLastName() + "%"));
            }
            Predicate[] p = personPredicates.toArray(new Predicate[personPredicates.size()]);
            personSubquery.where(cb.and((javax.persistence.criteria.Predicate[]) p));
            q.select(root).where(cb.exists(personSubquery));

            if (dto.getState() != null && !"".equals(dto.getState())) {
                Subquery<Address> addressSubquery = personSubquery.subquery(Address.class);
                Root<Address> addressInfo = addressSubquery.from(Address.class);
                List<Predicate> addressPredicates = new ArrayList<>();
                addressSubquery.select(addressInfo.get("addressId"));
                addressPredicates
                        .add(cb.equal(addressInfo.<String>get("addressId"), addressInfo.<String>get("addressId")));
                addressPredicates.add(cb.equal(addressInfo.<String>get("state"), dto.getState()));
                Predicate[] p1 = addressPredicates.toArray(new Predicate[addressPredicates.size()]);
                addressSubquery.where(cb.and((javax.persistence.criteria.Predicate[]) p1));
                personSubquery.select(personInfo).where(cb.exists(addressSubquery));
            }
        }

        if (dto.getUserGroups() != null && !"".equals(dto.getUserGroups())) {
            String[] userGroups = Utilities.getStringArray(dto.getUserGroups(), ",");
            Subquery<SecurityGroupings> securityGroupingSubquery = q.subquery(SecurityGroupings.class);
            Root<SecurityGroupings> securityGroupingInfo = securityGroupingSubquery.from(SecurityGroupings.class);
            List<Predicate> securityGroupingPredicates = new ArrayList<>();
            securityGroupingPredicates.add(
                    cb.equal(securityGroupingInfo.<String>get("id.securityUsers_1.name"), root.<String>get("name")));
            Predicate[] p2 = securityGroupingPredicates.toArray(new Predicate[securityGroupingPredicates.size()]);
            securityGroupingSubquery.where(cb.and((javax.persistence.criteria.Predicate[]) p2));
            q.select(root).where(cb.exists(securityGroupingSubquery));
        }
        q.where(cb.and((javax.persistence.criteria.Predicate[]) p0));
        TypedQuery<SecurityUsers> typedQuery = em.createQuery(q);
        // typedQuery.setFirstResult(pagingDTO.getFirstResult());
        // typedQuery.setMaxResults(10);
        List<SecurityUsers> resultList = typedQuery.getResultList();

我的代码无法生成正确的查询。正在生成的查询是这样的:

select securityus0_.name as name1_71_, securityus0_.description as description2_71_, securityus0_.su_person_id as su_person_id3_71_, securityus0_.priority as priority4_71_, securityus0_.user_type as user_type5_71_, securityus0_.email_address as email_address6_71_, securityus0_.su_shared_logon_flag as su_shared_logon_fl7_71_, securityus0_.su_create_username as su_create_username8_71_, securityus0_.su_create_date as su_create_date9_71_, securityus0_.su_update_username as su_update_usernam10_71_, securityus0_.su_user_agency as su_user_agency11_71_, securityus0_.su_active_flag as su_active_flag12_71_, securityus0_.su_update_date as su_update_date13_71_, securityus0_.su_expedite_flag as su_expedite_flag14_71_, securityus0_.su_ow_id as su_ow_id15_71_ from gm.security_users securityus0_ where exists (select person1_.person_id from gm.person person1_ where exists (select address2_.address_id from gm.address address2_ where address2_.address_id=address2_.address_id and address2_.a_state=?))

0 个答案:

没有答案