java - 向条件查询添加参数的最简单方法

标签 java jpa criteria

我想为您有一个查询方法的情况找到最简单的解决方案,该方法采用实体的某些属性,并基于该属性执行返回该实体的查询。

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

  • map 是硬编码的
  • 您必须将 key 存储在某处
  • 可能会出现输入错误
  • 等等

关于java - 向条件查询添加参数的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26661063/

相关文章:

java - org.hibernate.QueryException : unexpected char: '` '

java - 标准(不适用)

Hibernate 使用带有条件的别名

java - 禁用 JGraphX 上实际顶点的连接

java - 在Java中使用方法和数组时出现“Cannot find symbol”错误

java - 如何使用 JPA 和实体对象生命周期

JPA/Hibernate @OrderBy 注释,带有多个列和每个列的 ASC/DESC

java - 实体之间没有关系的 Hibernate Criteria 查询

java - 使用 Spring OSGi 时,BundleActivator 无法解析为类型

java - 相当于 Java 中的 VBA With 语句