Spring数据规范 - 如何通过多个属性过滤对象

时间:2017-08-23 17:12:37

标签: java spring spring-data-jpa predicates jpa-criteria

我尝试通过多个属性实现对用户的搜索。 让我们说,我的人有名字和姓氏。我想输入Michael Doe'并列出具有此名称和姓氏的所有人员。当我只输入“迈克尔”时,我想要所有迈克尔等等。

我试图通过使用谓词来实现它:

private static Specification<UserEntity> containsTextInAttributes(List<String> text, List<String> attributes) {
    List<String> finalTextArray = text.stream().map(e -> "%"+e+"%").collect(Collectors.toList());
    return (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream()
            .filter(a -> attributes.contains(a.getName()))
            .map(a -> builder.or(finalTextArray.stream().map(e -> builder.like(root.get(a.getName()), e)).toArray(Predicate[]::new)))
            .toArray(Predicate[]::new)
    );
}

public static Specification<UserEntity> containsTextInAllAttributes(List<String> text) {
    return containsTextInAttributes(text, Arrays.asList("lastname", "firstname", "email", "phoneNumber"));
}

然而,当我搜索Michael Doe&#34;我有所有Michaels和所有与姓氏Doe。我怎样才能解决我的问题?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我。 "Michael D", "firstName", "lastName""mdoe@gmail", "email"

public <T> Specification<T> dynamicLike(String likeValue, String... properties) {
    return (Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {

        Expression<String> concat = null;

        for (String property : properties) {
            if (concat == null) {
                concat = cb.concat("", root.get(property));
            } else {
                concat = cb.concat(concat, cb.concat(" ", root.get(property)));
            }
        }

        return cb.like(cb.lower(concat), "%" + likeValue.toLowerCase() + "%");
    };
}

II。 "Mic Do @gmail", "firstName", "lastName", "email"

public <T> Specification<T> dynamicLike2(String value, String... properties) {
    return (Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {

        String[] values = value.split("\\s");
        int minNumber = Integer.min(values.length, properties.length);

        Predicate[] likes = new Predicate[minNumber];

        for (int i = 0; i < minNumber; i++) {
            likes[i] = cb.like(cb.lower(root.get(properties[i])), "%" + values[i].toLowerCase() + "%");
        }

        return cb.and(likes);
    };
}