如何把mybatics化成jpa的高级查询呢?用Specification写。。。

如,mybatics代码:

 exists (

        select r.role_id,p.dep_port_id,p.des_port_id from s_port_auth p

        left join s_role r on r.role_id = p.role_id

        where
                    r.role_id in (${authRoleIds}) and nvl(r.is_limit_port,0)=1
                    and
                    nvl(nvl(p.dep_port_id,nvl(tab.barge_dep_port_id,tab.dep_port_id)),0) = nvl(nvl(tab.barge_dep_port_id,tab.dep_port_id),0)
                    and
                    nvl(nvl(p.des_port_id,nvl(tab.barge_des_port_id,tab.des_port_id)),0) = nvl(nvl(tab.barge_des_port_id,tab.des_port_id),0) )

如何写成一个子查询呢???


        Specification<BusOrder> spec = new Specification<BusOrder>() {

            @Override
            public Predicate toPredicate(Root<BusOrder> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

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


                 if (searchParams.get("busNum_like") != null) {

                 list.add(cb.like(root.get("busNum").as(String.class), "%" +searchParams.get("busNum_like") + "%"));

                 }

                 if (searchParams.get("enterpriseByShipper.name_like") !=null) {

                 list.add(cb.like(root.join("enterpriseByShipper").get("name").as(String.class),"%" + searchParams.get("enterpriseByShipper.name_like") +"%"));

                 }

                 if (searchParams.get("busType") != null) {

                 list.add(cb.equal(root.get("busType").as(Integer.class),searchParams.get("busType")));

                 }

                if (user.getIsLimitPort() == 1 && user.getRoleIds() != null) {

//这里如何把上面的mybatics转为一个子查询呢?
//我如下写,写得好乱啊。。。求指教
                    Subquery<String> first=query.subquery(String.class);
                    Root<PortAuth> rootAuth=first.from(PortAuth.class);
                    Path<String> pathOne=rootAuth.get("depPortId");
                    Join<PortAuth, Role> qq=rootAuth.join("roleId", JoinType.LEFT);
                    qq.on(cb.equal(qq.get("roleId"), rootAuth.get("roleId")));
                    first.where(cb.and());

                    list.add(cb.exists(first));

                }

                // 条件搜索
                Predicate[] p = new Predicate[list.size()];

                return cb.and(list.toArray(p));
            }
        };