将参数添加到条件查询的最简单方法

问题描述:

我想找到最简单的解决方案,以查找具有查询方法的情况,该查询方法采用某个实体的某个属性,并基于该属性执行返回该实体的查询。将参数添加到条件查询的最简单方法

问题是,如果我想添加更多可以搜索实体的属性,使用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建议,可以使用键/值对的机制来存储使用键作为属性/字段名和值字段的值搜索过滤器,但这种方法也有一些缺点:

  • 地图是硬编码
  • 你要存储密钥的地方
  • 打错可以做到