程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了用于多对多单向关系的Spring Data JPA规范大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决用于多对多单向关系的Spring Data JPA规范?

开发过程中遇到用于多对多单向关系的Spring Data JPA规范的问题如何解决?下面主要结合日常开发的经验,给出你关于用于多对多单向关系的Spring Data JPA规范的解决方法建议,希望对你解决用于多对多单向关系的Spring Data JPA规范有所启发或帮助;

总览

此规范的棘手之处在于,您要查询的 Catowner 没有直接关系。

总体思路是:

  • 获取 所有者
  • 使用 owner.cats 关系成员关系将 所有者Cat 相关联。我们可以只使用实体来完成此操作,就像JPA一样为我们处理实体@ID相关性。 __
  • Cat 上的查询标记为 disTinct 。为什么?因为这是@manyToMany关系,并且根据所 使用的所有者 条件,任何给定的 Cat 可能都有多个匹配的 所有者

方法1-子查询

我的首选方法是使用子查询来引入 owner

// Subquery using Cat membership in the owner.cats relation
public static class Specs {
    static Specification<Cat> hasownername(final String ownerName) {
        return (root, query, cb) -> {
            query.disTinct(true);
            Root<Cat> cat = root;
            Subquery<owner> ownerSubquery = query.subquery(owner.class);
            Root<owner> owner = ownerSubquery.from(owner.class);
            Expression<Collection<Cat>> ownerCats = owner.get("cats");
            ownerSubquery.SELEct(owner);
            ownerSubquery.where(cb.equal(owner.get("name"), ownerName), cb.isMember(cat, ownerCats));
            return cb.exists(ownerSubquery);
        };
    }
}

哪个Hibernate 4.3.x会生成SQL查询,例如:

SELEct cat0_.ID as ID1_1_
from cat cat0_
where 
    exists (
        SELECT owner1_.ID from owner owner1_ where
            owner1_.name=?
            and (cat0_.ID in (
                SELEct cats2_.cat_ID from owner_2_cats cats2_ where owner1_.ID=cats2_.owner_ID
            ))
    )

方法2-笛卡尔积

一种替代方法是使用笛卡尔积介绍 所有者

// Cat membership in the owner.cats relation using cartesian product
public static class Specs {
    static Specification<Cat> hasownername(final String ownerName) {
        return (root, query, cb) -> {
            query.disTinct(true);
            Root<Cat> cat = root;
            Root<owner> owner = query.from(owner.class);
            Expression<Collection<Cat>> ownerCats = owner.get("cats");
            return cb.and(cb.equal(owner.get("name"), ownerName), cb.isMember(cat, ownerCats));
        };
    }
}

哪个Hibernate 4.3.x会生成SQL查询,例如:

SELEct cat0_.ID as ID1_1_
from cat cat0_
cross join owner owner1_
where
    owner1_.name=?
    and (cat0_.ID in (
        SELECT cats2_.cat_ID from owner_2_cats cats2_ where owner1_.ID=cats2_.owner_ID
    ))

解决方法

我有一个设置,其中猫可以由许多所有者拥有,每个所有者可以拥有几只猫。鉴于此,我想写一个说明来帮助我找到具有给定主人姓名的所有猫。

这是一个简单的类设置。

@Entity
public class Cat extends AbstractEntity {
  @column
  private String name;
}

*为简洁起见,没有getters / setter。id字段在超类中。

@Entity
public class owner extends AbstractEntity {
  @column
  private String name;

  @manyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "owneR_2_CATS",joincolumns = @Joincolumn(name = "owneR_ID"),inverseJoincolumns = @Joincolumn(name = "CAT_ID"))
  @Ordercolumn(name = "order_column")
  private List<Cat> cats = Lists.newArrayList();
}

*为简洁起见,没有getters / setter。id字段在超类中。

这是一个存储库,其中包含有效的查询和无效的规范。

public interface CatRepository extends AtomicsRepository<Cat,Long> {

  // This query works.
  @Query("SELECT c FROM owner o INNER JOIN o.cats c WHERE o.name = ?")
  List<Cat> findAllByowner(String ownerName);

  // But how do I accomplish this in a specification?
  public static class Specs {
    static Specification<Cat> hasownerName(final String ownerName) {
      return (root,query,cb) -> {
        // these next lines don't work! what do I put here?
        Root<owner> owner = query.from(owner.class);
        owner.join("cats");
        return cb.equal(owner.get("name"),ownerName);
      };
    }
  }
}

请帮我写规范。

我遇到的麻烦是,这种关系似乎需要与关系的表达方式背道而驰:所有者拥有cats列表,而猫则没有owners列表。

大佬总结

以上是大佬教程为你收集整理的用于多对多单向关系的Spring Data JPA规范全部内容,希望文章能够帮你解决用于多对多单向关系的Spring Data JPA规范所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。