7

我最近一直在努力用 spring data jpa 加入 3 个表。我有 3 个实体SeriesDossierItemSeries有很多Dossiers,并且Dossier有很多Items(关系)。我做了类似的事情Series.join(Dossier_.series).join(Dossier_.items),我最终得到了一个加入集。我想进行以下查询:

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

我不能用 Spring Specifications and criteria api 来表达这个声明....请解释一下

4

3 回答 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

或者,如果只包含@ManyToOnes 而省略@OneToManys 更合理,那么查询仍然是直截了当的:

from Item where i.dossier.series.projectId = :param
于 2013-01-29T00:50:25.357 回答
0

[在这里仍然很困难] 也许我没有说清楚。我知道如何用 HQL 表达查询。问题是使用 Spring Data 的规范,在标准 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 这样的标准。等于(join2.get(Series_.projectId),)

于 2013-01-29T08:24:58.160 回答
0

我使用弹簧数据接口投影。像这样的例子

注意项必须是接口类

存储库类

@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);

}
于 2019-03-20T08:36:20.297 回答