在Spring Jpa Data中连接3个表

7

最近我一直在努力使用Spring Data JPA连接三个表。 我有三个实体:SeriesDossierItemSeries包含多个Dossier,而Dossier又包含多个Item(关系)。 我做了如下操作:Series.join(Dossier_.series).join(Dossier_.items),然后得到了一个Join集合。 我想进行以下查询:

Select Items from Series,Dossier,Item 
Where Series.Id=Dossier.seriesId 
and Dossier.id=Item.dossierId 
and series.projectId = :param

我无法使用Spring规范和Criteria API来表达这个语句...请给予一些指引


我有类似的需求和问题。你解决了问题吗?能否回复@Rocky Savidis? - arch
3个回答

8

这更像是一个JPA问题。

首先,我要强调的是,你不应该访问“表格”,而应该将它们视为领域实体。许多对JPA / Hibernate /其他ORM的误用实际上来自于直接将SQL或数据库概念进行“翻译”。

回到你的问题,答案很简单。首先确保你在领域实体中实际拥有“关系”。存储ID并不能帮助构建具体的领域模型。例如,你可能会有以下内容:

@Entity
class Series {
  @Id
  Long id;

  @OneToMany(mappedBy="series")
  List<Dossier> dossiers;
}
@Entity
class Dossier{
  @Id
  Long id;

  @ManyToOne
  Series series;

  @OneToMany(mappedBy="dossier"
  List<Item> items;
}

@Entity
class Item{
  @Id
  Long id;

  @ManyToOne
  Dossier dossier;
}

这个查询很直接:

select s.dossiers.items from Series s where s.projectId = :param

或者,如果仅具有@ManyToOne并省略@OneToMany更为合理,则查询仍然很简单:

from Item where i.dossier.series.projectId = :param

0

我正在使用Spring Data接口投影。

注意:项目必须是接口类。

存储库类

@Repository
public interface ItemRepository extends JpaRepository<Items,Long> {

    @Query(nativeQuery = true,value = "Select Items from Series,Dossier,Item Where Series.Id=Dossier.seriesId and Dossier.id=Item.dossierId and series.projectId = :param")
    public Items findTransaksisByAccountIdOrderById(@Param("param") Long projectId);

}

0

[仍然有些困难]也许我没有表述清楚。我知道如何在HQL中表达查询。问题是如何使用Spring Data的Specifications,并借助Criteria API构建该查询。

//Let's exampine the following piece of code

        public class CustomItemSpecs {

        public static Specification<Item> createSpecificationFromSearchForm(final SearchForm searchForm) {  
            return new Specification<Item>() {
                @Override  
                public Predicate toPredicate(Root<Item> root, CriteriaQuery<?> query, CriteriaBuilder cb) {             
        CriteriaQuery<Item> cq = cb.createQuery(Item.class);


                    CriteriaQuery<Series> sb = cb.createQuery(Series.class);
                    Root<Series> series = sb.from(Series.class);

                    Join<Series,Dossier> join1 = series.join(Series_.dossiers);

                    Join<Dossier, Item> join2 = join1.join(Dossier_.items);
        }
}

    }

正如您所看到的,我成功地进行了两个单独的连接。问题是当我想要连接Series、Dossier和Items来执行上述查询时。请注意,join2是一个Dossier-Item集合。我无法像cb.equals(join2.get(Series_.projectId))这样制定条件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接