spring JPA 中IN 的用法

一些语法并不向mybatis那样灵活,写起来也是很费劲

1. 查询条件

比如:

        要实现某个查询条件,要满足

1. 改字段为空的场景,

2. 该字段不为空,但是要根据该条件再过滤一次的场景

2. 常规的sql两种实现方法

① select * from  a   A where A.sys_id is null union select * from a A  where A.sys_id is not null and A.sys_id in (select id from B where ..... );

② select * from  a   A where  A.sys_id is null or   A.sys_id in (select id from B where ..... );

以上两种sql对比,如果条件较少,①还可以,如果条件较多,并不怎么好写,同时性能

union要进行一次去重的操作。

我这个表大概50W条数据,而且不重复。所以系统每插入一条数据,就要走全表查一次索引,50W条数据就要查50W次,当然卡死。

提出建议:使用union all。这样就不会走去重的逻辑了。

因此想到了使用sql②,但是用jpa的sql语法并不像mybatis的写法那么灵活,该怎么写呢?

3 以下是jpa的sql

select ftagentpo0_.agentid as agentid1_1_, ftagentpo0_.clusterstate as clusters2_1_, ftagentpo0_.description as descript3_1_, ftagentpo0_.hport as hport4_1_, ftagentpo0_.agentip as agentip5_1_, ftagentpo0_.ismonitor as ismonito6_1_, ftagentpo0_.ismanually as ismanual7_1_, ftagentpo0_.agentname as agentnam8_1_, ftagentpo0_.password as password9_1_, ftagentpo0_.port as port10_1_, ftagentpo0_.priority as priorit11_1_, ftagentpo0_.serverid as serveri12_1_, ftagentpo0_.status as status13_1_, ftagentpo0_.sysid as sysid14_1_, ftagentpo0_.transferstatus as transfe15_1_, ftagentpo0_.updatetime as updatet16_1_, ftagentpo0_.agentver as agentve17_1_ from ft_agent ftagentpo0_ where ftagentpo0_.transferstatus=? and (ftagentpo0_.sysid is null or ftagentpo0_.sysid in (select ftsyspo1_.id from ft_sys ftsyspo1_ where ftsyspo1_.userid=?)) order by ftagentpo0_.sysid desc, ftagentpo0_.status asc, ftagentpo0_.agentid desc limit ?

4. 代码实现

protected Specification<FtAgentPO> createSpec(FtAgentPO.Criteria criteria,String type) {
        Specification<FtAgentPO> spec = (root, query, builder) -> {
            if (criteria == null) {
                return builder.and(new Predicate[]{});
            }
            List<Predicate> predicates = new ArrayList<Predicate>();
            Optional.ofNullable(criteria.getSysId()).ifPresent((value) -> predicates.add(builder.equal(root.get("sysId"), value)));
            Optional.ofNullable(criteria.getServerId()).ifPresent((value) -> predicates.add(builder.equal(root.get("serverId"), value)));
            Optional.ofNullable(criteria.getIp()).ifPresent((value) -> predicates.add(JPAPredicateHelper.like(builder, root.get("ip"), value)));
            Optional.ofNullable(criteria.getStatus()).ifPresent((value) -> predicates.add(builder.equal(root.get("status"), value)));
            Optional.ofNullable(criteria.getZone()).ifPresent((value) -> predicates.add(builder.equal(root.get("zone"), value)));
            Optional.ofNullable(criteria.getEnv()).ifPresent((value) -> predicates.add(builder.equal(root.get("env"), value)));
            Optional.ofNullable(criteria.getClusterState()).ifPresent((value) -> predicates.add(builder.equal(root.get("clusterState"), value)));
            if(type.equals("eq")){
                Optional.ofNullable(criteria.getName()).ifPresent((value) -> predicates.add(builder.equal(root.get("name"), value)));
            }else {
                Optional.ofNullable(criteria.getName()).ifPresent((value) -> predicates.add(JPAPredicateHelper.like(builder, root.get("name"), value)));
            }
            Optional.ofNullable(criteria.getTransferStatus()).ifPresent((value) -> predicates.add(builder.equal(root.get("transferStatus"), value)));
            if (criteria.getSysIdIsNull() != null) {
                if (criteria.getSysIdIsNull()) {
                    predicates.add(builder.isNull(root.get("sysId")));
                } else {
                    predicates.add(builder.isNotNull(root.get("sysId")));
                    handleUserSys(root, query, builder, predicates);
                }
            } else {
                handleUserSys(root, query, builder, predicates);
            }
            return builder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        return spec;
    }
   private void handleUserSys(Root<FtAgentPO> root, CriteriaQuery<?> query, CriteriaBuilder builder, List<Predicate> predicates) {
        if (!BFTModelHelper.checkAdmin()){
            String userId = BFTModelHelper.getUserId();

            Subquery<String> subsubquery = query.subquery(String.class);
            Root<FtSysPO> subsubroot = subsubquery.from(FtSysPO.class);
            subsubquery.select(subsubroot.get("id"));
            subsubquery.where(builder.equal(subsubroot.get("userId"), userId));

            Predicate managePredicate = builder.or(
                    builder.isNull(root.get("sysId")),
                    root.get("sysId").in(subsubquery)
            );
            predicates.add(managePredicate);
        }
    }

主要是以上的sql写法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值