加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

组合弹簧数据规范的查询在同一个表上有多个连接

发布时间:2020-12-14 23:55:40 所属栏目:Java 来源:网络整理
导读:对不起,如果我的术语不正确. 我们使用spring数据,JpaRepositories和条件查询作为查询数据库数据的方法. 我有一个问题,当我在下面的代码示例中结合两个规范,例如我在hasCityAndTimeZone中使用hasTimeZone和hasCity时,它会在同一个表上连接两次,所以下面的查询
对不起,如果我的术语不正确.

我们使用spring数据,JpaRepositories和条件查询作为查询数据库数据的方法.

我有一个问题,当我在下面的代码示例中结合两个规范,例如我在hasCityAndTimeZone中使用hasTimeZone和hasCity时,它会在同一个表上连接两次,所以下面的查询看起来像

select * from Staff,Location,Location

有没有办法让这两个规范使用相同的连接而不是每个定义它们自己的连接基本相同?

对不起代码可能不完整我只是想展示一个简单的例子.

class Staff {
    private Integer id;
    private Location location;
}

class Location {
    private Integer id; 
    private Integer timeZone;
    private Integer city;
}

class StaffSpecs {
    public static Specification<Staff> hasTimeZone(Integer timeZone) {
        return new Specification<Staff>() {
            @Override
            public Predicate toPredicate(Root<Staff> root,CriteriaQuery<?> query,CriteriaBuilder cb) {
                Path<Integer> timeZonePath = root.join(Staff_.location).get(Location_.timeZone);
                return cb.equal(timeZonePath,timeZone);
            }
        }
    }

    public static Specification<Staff> hasCity(Integer city) {
        return new Specification<Staff>() {
            @Override
            public Predicate toPredicate(Root<Staff> root,CriteriaBuilder cb) {
                Path<Integer> cityPath = root.join(Staff_.location).get(Location_.city);
                return cb.equal(cityPath,city);
            }
        }
    }

    public static Specification<Staff> hasCityAndTimeZone(Integer city,Integer timeZone) {
        return where(hasCity(city)).and(hasTimeZone(timeZone));
    }
}

解决方法

不幸的是,没有开箱即用的方式. Spring Data在内部使用QueryUtils.getOrCreateJoin(…)中的一些连接重用.您可以在根上找到可能已存在的连接,并在适当的地方重用它们:
private static Join<?,?> getOrCreateJoin(From<?,?> from,String attribute) {

  for (Join<?,?> join : from.getJoins()) {

    boolean sameName = join.getAttribute().getName().equals(attribute);

    if (sameName && join.getJoinType().equals(JoinType.LEFT)) {
      return join;
    }
  }

  return from.join(attribute,JoinType.LEFT);
}

请注意,这只有在我们有效地知道自己添加哪些连接时才有效.使用规格时你也应该这样做,但我只是想确保没有人认为这是所有情况下的通用解决方案.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读