在JPA CriteriaBuilder联接查询中仅获取一个子项
我有两个实体:在JPA CriteriaBuilder联接查询中仅获取一个子项,jpa,entity,criteria,entitymanager,hibernate-criteria,Jpa,Entity,Criteria,Entitymanager,Hibernate Criteria,我有两个实体: public class Tyre { @Id @Column(name = "tyreid") @GeneratedValue private int tyreid; @Column(name = "brand") private String brand; @Column(name = "tyretype") private String tyretype; @OneToMany(targetEntity = TyreAuto.class, cascade
public class Tyre {
@Id
@Column(name = "tyreid")
@GeneratedValue
private int tyreid;
@Column(name = "brand")
private String brand;
@Column(name = "tyretype")
private String tyretype;
@OneToMany(targetEntity = TyreAuto.class, cascade = CascadeType.ALL)
@JoinColumn(name = "tyreid",referencedColumnName = "tyreid")
private List<TyreAuto> tyreAutos;
}
我有以下返回json响应的代码:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tyre> criteriaQuery = criteriaBuilder.createQuery(Tyre.class);
Metamodel m = entityManager.getMetamodel();
EntityType<Tyre> Tyre_ = m.entity(Tyre.class);
Root<Tyre> tyreRoot = criteriaQuery.from(Tyre_);
Join<Tyre,TyreAuto> tyreAutos = tyreRoot.join("tyreAutos",JoinType.INNER);
Predicate predicateForBrand
= criteriaBuilder.equal(tyreRoot.get("brand"), "Firestone");
Predicate predicateForSerie
= criteriaBuilder.equal(tyreAutos.get("serie"),"XYZ");
Predicate predicateForBrandAndSerie
= criteriaBuilder.and(predicateForSerie,predicateForBrand);
criteriaQuery.where(predicateForBrandAndSerie);
List<Tyre> items = entityManager.createQuery(criteriaQuery).getResultList();
if (!items.equals(null)) {
return new ResponseEntity<>(items, HttpStatus.OK);
} else {
return new ResponseEntity(ResponseEntity.notFound().build(),HttpStatus.NOT_FOUND);
}
我的问题是:
- 如果我正在筛选,为什么会获得多个儿童注册 意甲:“XYZ”李>
- 如何只获取一个子元素而不是全部3个子元素
[
{
"tyreid": 1,
"brand": "Firestone",
"tyretype": "Big",
"tyreAutos": [
{
"tyreautoid": 38,
"serie": "XYZ",
"tyreid": 13
}
]
}
]
为什么我得到一个以上的儿童注册,如果我过滤系列:“XYZ”
您将获得声明为criteriaBuilder.createQuery(Tyre.class)
的整个Tyre
对象,其中brand=“Firestone”
和tyreAutos
包含tyreAuto
和serie=“XYZ”
如何只获取一个子元素而不是全部3个子元素
要仅获取一个TyreAuto
,可以像这样使用反向查询criteriaBuilder.createQuery(TyreAuto.class)
以这种方式更改实体
public class TyreAuto {
@Id
@Column(name = "tyreautoid")
@GeneratedValue
private int tyreautoid;
@Column(name = "serie")
private String serie;
@ManyToOne
@JoinColumn(name = "tyreid")
private Tyre tyre;
}
现在您可以从TyreAuto
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<TyreAuto> criteriaQuery = criteriaBuilder.createQuery(TyreAuto.class);
Metamodel m = entityManager.getMetamodel();
EntityType<TyreAuto> TyreAuto_ = m.entity(TyreAuto.class);
Root<TyreAuto> tyreAutoRoot = criteriaQuery.from(TyreAuto_);
Join<TyreAuto, Tyre> tyre = tyreAutoRoot.join("tyre",JoinType.INNER);
Predicate predicateForBrand
= criteriaBuilder.equal(tyre.get("brand"), "Firestone");
Predicate predicateForSerie
= criteriaBuilder.equal(tyreAutoRoot.get("serie"),"XYZ");
criteriaQuery.select(tyreAutoRoot).where(predicateForSerie, predicateForBrand);
List<TyreAuto> items = entityManager.createQuery(criteriaQuery).getResultList();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery-CriteriaQuery=criteriaBuilder.createQuery(TyreAuto.class);
元模型m=entityManager.getMetamodel();
EntityType TyreAuto=m.entity(TyreAuto.class);
Root tyreAutoRoot=criteriaQuery.from(TyreAuto_);
Join tyre=tyreAutoRoot.Join(“轮胎”,JoinType.INNER);
谓词forbrand
=criteriaBuilder.equal(轮胎获得(“品牌”),“火石”);
谓词forserie
=criteriaBuilder.equal(tyreAutoRoot.get(“系列”),“XYZ”);
select(tyreAutoRoot).where(predicateForSerie,predicateForBrand);
List items=entityManager.createQuery(criteriaQuery.getResultList();
另一个选项是使用
dto
类作为查询结果。您可以根据需要对其进行配置。你可以得到更多信息。阅读“条件查询”中的“数据到投影”一章要仅获取特定字段,您应该使用投影而不是实体作为查询结果。我给了你一个链接,在我答案的底部有解释
public class TyreAuto {
@Id
@Column(name = "tyreautoid")
@GeneratedValue
private int tyreautoid;
@Column(name = "serie")
private String serie;
@ManyToOne
@JoinColumn(name = "tyreid")
private Tyre tyre;
}
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<TyreAuto> criteriaQuery = criteriaBuilder.createQuery(TyreAuto.class);
Metamodel m = entityManager.getMetamodel();
EntityType<TyreAuto> TyreAuto_ = m.entity(TyreAuto.class);
Root<TyreAuto> tyreAutoRoot = criteriaQuery.from(TyreAuto_);
Join<TyreAuto, Tyre> tyre = tyreAutoRoot.join("tyre",JoinType.INNER);
Predicate predicateForBrand
= criteriaBuilder.equal(tyre.get("brand"), "Firestone");
Predicate predicateForSerie
= criteriaBuilder.equal(tyreAutoRoot.get("serie"),"XYZ");
criteriaQuery.select(tyreAutoRoot).where(predicateForSerie, predicateForBrand);
List<TyreAuto> items = entityManager.createQuery(criteriaQuery).getResultList();