【问题标题】:How to create a CriteriaBuilder expression in runtime for nested attributes?如何在运行时为嵌套属性创建 CriteriaBuilder 表达式?
【发布时间】:2019-06-03 14:36:04
【问题描述】:

我正在尝试使用 Criteria API 创建一个用于深度过滤的通用方法。

例如,如果我想过滤属性“id.person.name”或超过 3 个嵌套属性。

我已经有 2 个嵌套属性的过滤器在工作,例如:“person.name”。

下面的 elseif 条件适用于 3 个嵌套属性,但我正在尝试创建一个在出现新案例时无需更改的方法。

private <T> List<Predicate> filterInDepth(Map<String, String> params, Root<T> root,
        CriteriaBuilder criteriaBuilder, String field, Class<T> clazz)
        throws NoSuchFieldException {
    List<Predicate> predicates = new ArrayList<>();
    String[] compositeFields = field.split(REGEX_FIELD_SPLITTER);
    if (compositeFields.length == 2) {
        Join<Object, Object> join = root.join(compositeFields[0]);
        predicates.add(criteriaBuilder.equal(join.get(compositeFields[1]),
                params.get(field)));
    }
    else if (clazz.getDeclaredField(compositeFields[0]).getType()
            .getDeclaredField(compositeFields[1]).getType()
            .getDeclaredField(compositeFields[2]) != null) {
        predicates.add(criteriaBuilder.equal(root.get(compositeFields[0])
                .get(compositeFields[1]).get(compositeFields[2]), params.get(field)));
    }
    return predicates;
}

所以我正在尝试拆分字符串、循环并创建一个表达式。但我无法连接表达式。

【问题讨论】:

    标签: java jpa criteria criteria-api


    【解决方案1】:

    我找到了一个解决方案,希望对某人有所帮助。

    private <T> List<Predicate> filterInDepth(Map<String, String> params, Root<T> root,
            CriteriaBuilder criteriaBuilder, String field, Class<T> clazz)
            throws NoSuchFieldException {
        List<Predicate> predicates = new ArrayList<>();
        String[] compositeFields = field.split(REGEX_FIELD_SPLITTER);
    
        if (isNestedFieldExists(clazz, compositeFields)) {
            Path path = null;
            for (String part : compositeFields) {
                if (path == null) {
                    path = root.get(part);
                }
                else {
                    path = path.get(part);
                }
            }
    
            predicates.add(criteriaBuilder.equal(path, params.get(field)));
        }
    
        return predicates;
    }
    
    private boolean isNestedFieldExists(Class clazz, String[] fieldChain)
            throws NoSuchFieldException {
        for (String field : fieldChain) {
            Field f = clazz.getDeclaredField(field);
            if (f.getType() == null) {
                return false;
            }
    
            clazz = f.getType();
        }
    
        return true;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-19
      • 2013-12-31
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多