与 Criteria 无关的实体的左外连接

T3r*_*rm1 5 java hibernate jpa criteria

如果该实体未映射,是否可以创建一个对另一个实体执行外连接的条件查询?

我知道当您进行交叉连接并手动添加连接条件时,可以进行内部连接。它看起来像这样:

CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();

Root<Car> car = cq.from(Car.class);
Root<Color> color = cq.from(Ccolor.class);

cq.where(cb.equal(car.get("colorUuid"), color.get("uuid")));
Run Code Online (Sandbox Code Playgroud)

但是,在我的情况下,我需要外部联接的行为。

假设我有这些实体:

CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();

Root<Car> car = cq.from(Car.class);
Root<Color> color = cq.from(Ccolor.class);

cq.where(cb.equal(car.get("colorUuid"), color.get("uuid")));
Run Code Online (Sandbox Code Playgroud)

可以说颜色是可选的,这就是我需要外部连接的原因。SQL 看起来像

class Car {
  @Column(name="color_uuid")
  private String colorUuid;
}

class Color {
  private String uuid;
  private String name;
}
Run Code Online (Sandbox Code Playgroud)

我可以用 Criteria 来做到这一点吗?

小智 -2

我建议您更改类,以便建立逻辑上已经存在的关系。

class Car {
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "color_uuid", referencedColumnName = "uuid")
    private Color color;
}

class Color {
    private String uuid;
    private String name;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "color")
    private List<Car> cars;
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用条件构建左连接:

CriteriaQuery<Car> criteriaQuery = criteriaBuilder.createQuery(Car.class);
Root<Car> root = criteriaQuery.from(Car.class);
root.join("color", JoinType.LEFT);
List<Car> cars = em.createQuery(criteriaQuery).getResultList();
Run Code Online (Sandbox Code Playgroud)

  • 我不想添加映射。这就是为什么我明确要求提供不相关的实体。 (2认同)