我面临着多个选择查询(N+1)到JOIN.ON的条件。下面是我的例子
这是我的映射 人物 实体
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumns({
@JoinColumn(name = "vehicleId", referencedColumnName = "vehicleId")
})
@WhereJoinTable( clause = "vehicle_color = 'RED' " ) - I did try this annotation but dont see conditional join in hibernate generated query
private Vehicle vehicle;
所以我尝试使用CriteriaBuilder
Join<Person, Car> vehicleJoin = personJoin.join("vehicle", JoinType.LEFT);
vehicleJoin.on(criteriaBuilder.isNotNull(personJoin.get(" vehicle_color = 'RED' ")))
当我添加了vehicleJoin.on条件后,我确实看到它正确地加入了,但它正在为该人的每一辆车执行select查询。
我想避免多次选择,并获取所有车辆数据作为主查询的一部分。
下面是在我的项目中使用的罐子
spring-boot-starter-data-jpa 2.1.6
Hibernate-core 5.3.10
先谢谢大家的意见。希望能更容易阅读和理解 :D
我想你是在写一个实体查询?这其实是不可能的,因为你必须使用一个带有ON条件的fetch join。因为这将改变集合的持久化状态,可能会导致意外的删除,在JPA中是不允许的。
你需要一个元组查询来代替,即一个自定义的投影。
这是一个完美的用例 Blaze-持久性实体视图.
我创建这个库的目的是为了让JPA模型和自定义接口或抽象类定义的模型之间能够轻松地进行映射,就像Spring Data Projections一样。这个想法是,你以你喜欢的方式定义你的目标结构(领域模型),并通过JPQL表达式将属性(getters)映射到实体模型。由于属性名被用作默认映射,你大多不需要显式映射,因为80%的用例是拥有实体模型子集的DTO。
一个示例模型可以像下面这样。
@EntityView(Person.class)
public interface PersonView {
@IdMapping
Integer getId();
@Mapping("vehicle[color = 'RED']")
VehicleView getVehicle();
}
@EntityView(Vehicle.class)
public interface VehicleView {
@IdMapping
Integer getId();
String getName();
}
查询是将实体视图应用到查询中的问题,最简单的就是通过id进行查询。
PersonView p = entityViewManager.find(entityManager, PersonView.class, id);
Spring Data集成允许你使用它,几乎就像Spring Data Projections一样。https:/persistence.blazebit.comdocumentationentity-viewmanualen_USindex.html#spring-data-features。 即有一个类似于以下的仓库
@Repository
public interface PersonRepository {
PersonView findById(Integer id);
}