我最近一直在努力与春季数据jpa一起加入3个牌桌。我有3个实体,Series
,Dossier
和Item
。 Series
有很多Dossiers
,Dossier
有很多Items
(关系)。我做了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规范和标准api表达这个声明....请说清楚
答案 0 :(得分:6)
这更像是一个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
答案 1 :(得分: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来执行上面的查询.Notice,join2是一个档案项集。我不能制定标准比如cb.equals(join2.get(Series_.projectId),)
答案 2 :(得分:0)
im使用spring数据接口投影。 这样的例子
注释项目必须是界面类
存储库类
@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);
}