如何查询加入@ManyToOnes 表 PostgreSQL Spring Boot JPA

How can I make a query joining @ManyToOnes tables PostgreSQL SpringBoot JPA

我目前正在为一个我知道可能的查询而苦苦挣扎,但由于我在 SQL 查询方面的技能不佳,我无法真正设法找到正确的句子。

我想找到某个区域的所有领土。每个 Zone 包含多个 Territory,但一个 Territory 可以属于一个 Zone。实体如下:

public class Territory {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    private String name;

    private Long owned_player;

    @OneToMany
    private List<Territory> neighbors;

    private int no_of_armies;

    public Territory(String name) {
        this.no_of_armies = 0;
        this.neighbors = new ArrayList<>();
        this.name = name;
        //this.owned_player = new Player(0);
        this.owned_player = null;
    }
@Entity
public class Zone {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    private String name;
    private String map;
    //private int control_value;
    @OneToMany
    private List<Territory> territories;

    public Zone(String name, String map) {
        this.territories = new ArrayList<>();
        this.name = name;
        this.map = map;
        //this.control_value = control_value;
    }

我必须插入查询的存储库如下所示:

public interface TerritoryRepository extends JpaRepository<Territory,Long> {

    @Query("????")
    public List<Territory> findAllTerritoriesByZone(String zone);

}

我正在尝试查找将 return 属于亚洲(中国、日本、台湾...)或欧洲(西班牙、法国、德国...)的所有地区的查询。

感谢您的帮助和关注!

你的例子有一些问题,一旦你开始 运行 它就会有问题,但现在我将专注于你的具体问题的答案。

在您的示例中,Zone 和 Territory 之间的关系是单向的。 Zone#territories 意味着如果你有一个区域,你可以导航到它的领土。但是由于 Territory 没有引用 Zone,因此您不能遍历该方向 - 这将成为您问题的问题,因为这实际上就是您要尝试做的事情。

因此,您需要做的第一件事就是建立双向关系。

您可以通过在 Territory class:

上添加对区域的引用来实现
    @ManyToOne
    @JoinColumn(name = "ZONE_ID")
    private Zone zone;

然后用 mappedBy 属性更新 Zone#territories,以便 JPA 实现可以理解这两个字段相互引用。

    @OneToMany(mappedBy = "zone")
    private List<Territory> territories = new ArrayList<>();

有了它,您现在可以从存储库中的区域引用区域。在您的存储库中,我不清楚 zone 参数应该指的是什么 - 区域名称?如果是这样,您可以使用此查询来查找具有特定名称区域的地区:

    // in TerritoryRepository 
    @Query("select t from Territory t join t.zone where t.zone.name = :zone")
    public List<Territory> findAllTerritoriesByZone(String zone);

也可以使用常规派生查询来表达这一点,在这种情况下,您根本不需要指定 @Query/JPQL:

    List<Territory> findAllByZoneName(String zone);

示例的其他问题:

  • Territory 需要一个 @Entity 注释
  • Territory#neighbors表示为@OneToMany关系。这可能应该是一种 @ManyToMany 关系,因为您可以有很多邻居,而每个邻居都有很多邻居。为了这个答案的其余部分,我将其注释掉了。
  • 您的 TerritoryZone 没有默认构造函数。 JPA 要求实体具有默认的 public/protected 构造函数,以便它可以反射性地实例化它们。我将这些添加回去以使示例正常工作。