Boot Application and need a query with dynamic where field. Googling about it I've found Specifications could be an answer but how a make the where clause searching in attributes in different classes?
启动应用程序并需要具有动态where字段的查询。谷歌搜索我发现规格可能是一个答案,但如何使where子句在不同的类中搜索属性?
Here's my model
这是我的模特
Brand Class
品牌类
@Entity
public class Brand {
@Id
private Long id;
private String name;
@OneToMany(mappedBy="brand",cascade=CascadeType.ALL)
private Set<Cars> cars;
//Getter's and Setters
}
Car Class
汽车类
@Entity
public class Car {
@Id
private Long id;
private String name;
private String carType;
@ManyToOne(cascade=CascadeType.ALL)
private brand brand;
//Getter's and Setters
}
The repository is the strait one:
存储库是海峡的:
public interface CarRepository extends JpaRepository<Car, Long>, JpaSpecificationExecutor<Car> {
}
If the user enters the car's name and the brand i need something like the following jpql
如果用户输入汽车的名称和品牌我需要类似下面的jpql
select c from car c join c.brand br where br.name = :brandName and c.name = :carName
Also the user can enter only with the type of the car, so the jpql will be:
用户也可以只输入汽车的类型,所以jpql将是:
select c from car c join c.brand br where br.name = :brandName and c.carType = :carType
1 个解决方案
#1
0
Specifications are commonly used when you need to build dynamic queries. If your use case is limited to those two queries, I would rather write those as static queries and have a simple if/else to check if the name or type was provided.
当您需要构建动态查询时,通常会使用规范。如果您的用例仅限于这两个查询,我宁愿将它们写为静态查询,并使用简单的if / else检查是否提供了名称或类型。
When you use specifications and you follow the Spring guides, you should write an additional class that has your various specifications, for example:
当您使用规范并遵循Spring指南时,您应该编写一个具有各种规范的附加类,例如:
public class CarSpecifications {
public static Specification<Car> withBrandName(final String name) {
return (root, query, cb) -> {
final Path<Brand> brandPath = root.get("brand");
return cb.equal(brandPath.<String>get("name"), name);
};
}
// TODO: withName, withType
}
You'll have to add multiple methods here, the method above is only for your br.name = :brandName
clause.
您必须在此处添加多个方法,上述方法仅适用于您的br.name =:brandName子句。
Now, to use this class you have to write something like:
现在,要使用这个类,你必须写下这样的东西:
public List<Car> findCars(String brandName, String name, String type) {
Specifications<Car> spec = Specifications
.<>where(CarSpecifications.withBrandName(brandName));
if (name != null) {
spec.and(CarSpecifications.withName(name);
}
// TODO: if (type != null) ...
return repository.findAll(spec);
}
#1
0
Specifications are commonly used when you need to build dynamic queries. If your use case is limited to those two queries, I would rather write those as static queries and have a simple if/else to check if the name or type was provided.
当您需要构建动态查询时,通常会使用规范。如果您的用例仅限于这两个查询,我宁愿将它们写为静态查询,并使用简单的if / else检查是否提供了名称或类型。
When you use specifications and you follow the Spring guides, you should write an additional class that has your various specifications, for example:
当您使用规范并遵循Spring指南时,您应该编写一个具有各种规范的附加类,例如:
public class CarSpecifications {
public static Specification<Car> withBrandName(final String name) {
return (root, query, cb) -> {
final Path<Brand> brandPath = root.get("brand");
return cb.equal(brandPath.<String>get("name"), name);
};
}
// TODO: withName, withType
}
You'll have to add multiple methods here, the method above is only for your br.name = :brandName
clause.
您必须在此处添加多个方法,上述方法仅适用于您的br.name =:brandName子句。
Now, to use this class you have to write something like:
现在,要使用这个类,你必须写下这样的东西:
public List<Car> findCars(String brandName, String name, String type) {
Specifications<Car> spec = Specifications
.<>where(CarSpecifications.withBrandName(brandName));
if (name != null) {
spec.and(CarSpecifications.withName(name);
}
// TODO: if (type != null) ...
return repository.findAll(spec);
}