将参数添加到条件查询的最简单方法
问题描述:
我想找到最简单的解决方案,以查找具有查询方法的情况,该查询方法采用某个实体的某个属性,并基于该属性执行返回该实体的查询。将参数添加到条件查询的最简单方法
问题是,如果我想添加更多可以搜索实体的属性,使用jpa标准时最简单的解决方案是什么?这里的一个方面是该方法必须是可移植的 - 如果稍后添加属性,我不想重写所有的代码。
我知道这可以通过方法重载来完成,但我正在寻找更简单的解决方案。
例如我的方法的代码是:
public List<Car> findCar(String name) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Car> c = cb.createQuery(Car.class);
Root<Car> d = c.from(Car.class);
Predicate condition = cb.equal(d.get(Car_.name), name);
c.where(condition);
TypedQuery<Car> q = em.createQuery(c);
List<Car> results = q.getResultList();
return results;
}
,如果我想在某种程度上,我可以搜索其他属性租车实体扩展该查询,例如,日期,应该怎么办。我不希望这种方法需要多个参数。
答
我有点惊讶,这个问题以前没有在这里讨论过。
所以我做了一些调查,想出了可能的答案。
最简单的方法是拥有一个单独的类f.x. CarSearchFilter中,你可以(通过其要执行的查询,即参数)不同的过滤器:
public class CarSearchFilter {
private String name;
private Date date;
private String color;
//etc
//getters and setters
}
当您要添加新的参数进行查询,你只需要添加新的领域CarSearhFilter并修改查询这样方法。如果您不修改查询方法,它仍然按原样工作。这种API看起来很好。因此,findCar方法必须以这种方式修改:
public List<Car> findCar(CarSearchFilter filter) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Car> c = cb.createQuery(Car.class);
Root<Car> d = c.from(Car.class);
// you have to add more predicates when you want more parameters
List<Predicate> predicates = new ArrayList<Predicate>();
if (filter.getName() != null) {
predicates.add(cb.like(d.get(Car_.name), filter.getName()));
}
if (filter.getDate() != null) {
predicates.add(cb.lessThanOrEqualTo(d.get(Car_.date), filter.getDate()));
}
c.select(d).where(predicates.toArray(new Predicate[] {}));
TypedQuery<Car> q = em.createQuery(c);
List<Car> results = q.getResultList();
return results;
}
还有其他方法可以执行此任务。作为Tiny建议,可以使用键/值对的机制来存储使用键作为属性/字段名和值字段的值搜索过滤器,但这种方法也有一些缺点:
- 地图是硬编码
- 你要存储密钥的地方
- 打错可以做到
- 等