我尝试使用Specification来构建一个SQL,它“should”与下面的查询非常相似:
select p1_0.* from plans p1_0 inner join plans_vehicle_models p2_0 on p2_0.plan_id = p1_0.plan_id where p2_0.vehicle_model_id in (select v1_0.model_id from vehicle_models v1_0 where v1_0.model_name = 'ModelName')
尝试了所有的方法后,结果输出返回:
select p1_0.* from plans p1_0 join plans_vehicle_models p2_0 on p1_0.plan_id=p2_0.plan_id where p1_0.plan_id in((select v1_0.model_id from vehicle_models v1_0 where v1_0.model_name=?)).
简单地说,我希望where
子句是p2_0.vehicle_model_id
而不是p1_0.plan_id
下面是我的代码
规格等级
@Component
public class PlanSpecification {
public static Specification<Plan> vehicleModelNameExactlyIgnoringCase(String vehicleModelName) {
return ((root, query, criteriaBuilder) -> {
if (vehicleModelName != null) {
Subquery<Long> subquery = query.subquery(Long.class);
Root<VehicleModel> subqueryRoot = subquery.from(VehicleModel.class);
subquery.select(subqueryRoot.get("id"));
subquery.where(criteriaBuilder.equal(criteriaBuilder.upper(subqueryRoot.get("modelName")), vehicleModelName.toUpperCase()));
Join<Plan, PlanToVehicleModelAssignment> plansVehicleModelsJoin = root.join(Plan_.PLANS_VEHICLE_MODELS, JoinType.INNER);
return criteriaBuilder.in(root.get(PlanToVehicleModelAssignment_.ID)).value(subquery);
} else {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "`vehicle_model_name` parameter passed to filter resultset on Plan cannot be null");
}
});
}
}
计划模型类
@Data
@Entity
@Table(name = "plans")
public class Plan {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "plan_id", nullable = false, unique = true, columnDefinition = "BIGINT")
protected Long id;
@Column(name = "plan_code", unique = true, nullable = false)
protected String code;
@OneToMany(mappedBy = "plan", fetch = FetchType.LAZY)
protected List<PlanToVehicleModelAssignment> planToVehicleModelAssignmentList = new ArrayList<>();
}
PlanToVehicleModelAssignment模型类
@Table(name = "plans_vehicle_models")
public class PlanToVehicleModelAssignment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "plan_vehicle_model_id", columnDefinition = "BIGINT")
private Long id;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "plan_id", referencedColumnName = "plan_id")
private Plan plan;
@OneToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "vehicle_model_id", referencedColumnName = "model_id", unique = true)
private VehicleModel vehicleModel;
}
Plan_ MetaModel类
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Plan.class)
public abstract class Plan_ {
public static volatile SingularAttribute<Plan, Long> id;
public static volatile SingularAttribute<Plan, String> code;
public static volatile ListAttribute<Plan, PlanToVehicleModelAssignment> planToVehicleModelAssignmentList;
public static final String ID = "id";
public static final String CODE = "code";
public static final String PLANS_VEHICLE_MODELS = "planToVehicleModelAssignmentList";
}
PlanToVehicleModelAssignment_ metamodel类
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(PlanToVehicleModelAssignment.class)
public abstract class PlanToVehicleModelAssignment_ {
public static volatile SingularAttribute<PlanToVehicleModelAssignment, Long> id;
public static volatile SingularAttribute<PlanToVehicleModelAssignment, Plan> plan;
public static volatile SingularAttribute<PlanToVehicleModelAssignment, VehicleModel> vehicleModel;
public static final String ID = "id";
public static final String PLAN = "plan";
public static final String VEHICLE_MODEL = "vehicleModel";
}
1条答案
按热度按时间ig9co6j11#
我可以通过将上面Spec类上的返回行替换为
return criteriaBuilder.and(criteriaBuilder.in(plansVehicleModelsJoin.get(PlanToVehicleModelAssignment_.VEHICLE_MODEL)).value(subquery));
来解决这个问题工作规范类代码: