在Spring Jpa数据中连接3个表
我最近一直在努力用SpringDataJPA连接3个表。我有3个实体,在Spring Jpa数据中连接3个表,spring,jpa,join,Spring,Jpa,Join,我最近一直在努力用SpringDataJPA连接3个表。我有3个实体,系列,档案和项目系列有许多档案,档案有许多项目(关系)。我做了一些类似于Series.join(Dossier\uuuu.Series).join(Dossier\uuuuu.items)的事情,最终得到了一个连接集。我想进行以下查询: Select Items from Series,Dossier,Item Where Series.Id=Dossier.seriesId and Dossier.id=Item.dos
系列
,档案
和项目
<代码>系列有许多档案
,档案
有许多项目
(关系)。我做了一些类似于Series.join(Dossier\uuuu.Series).join(Dossier\uuuuu.items)
的事情,最终得到了一个连接集。我想进行以下查询:
Select Items from Series,Dossier,Item
Where Series.Id=Dossier.seriesId
and Dossier.id=Item.dossierId
and series.projectId = :param
我不能用Spring规范和标准api来表达这一说法……请解释一下,这更像是一个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;
}
或者,如果只使用@ManyToOne
s而忽略@OneToMany
s更合理,那么查询仍然是直接的:
select s.dossiers.items from Series s where s.projectId = :param
from Item where i.dossier.series.projectId = :param
[这里仍然是洛奇]也许我没有说清楚。我知道如何用HQL表达查询。问题是使用Spring数据的规范,借助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);
}
}
}
//让我们以下面的代码为例
公共类CustomItemSpecs{
公共静态规范createSpecificationFromSearchForm(最终SearchForm SearchForm){
返回新规范(){
@凌驾
公共谓词toPredicate(根根、CriteriaQuery查询、CriteriaBuilder cb){
CriteriaQuery cq=cb.createQuery(Item.class);
CriteriaQuery sb=cb.createQuery(Series.class);
根系列=来自(系列类)的sb;
Join join1=系列Join(系列档案);
Join join2=join1.加入(档案项目);
}
}
}
正如您所看到的,我成功地进行了两个独立的联接。问题是当我想要联接Series、Dossier和Items以执行上面的查询时。请注意,join2是一个Dossier项集。我不能使用spring数据接口投影来创建诸如cb.equals(join2.get(Series\ux.projectId))之类的条件。 像这样的例子 注意项必须是接口类 存储库类
@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);
}
@存储库
公共接口ItemRepository扩展了JpaRepository{
@查询(nativeQuery=true,value=“从系列、档案、项目中选择项目,其中Series.Id=Dossier.seriesId和Dossier.Id=Item.dossierId和Series.projectId=:param”)
通过AccountIdorDerbyid(@Param(“Param”)Long projectd)找到的公共物品;
}
我有类似的要求和同样的问题。什么解决了你的问题?你能回复@Rocky Savidis吗