Multi column search using Specifications Spring Data Jpa within associated entity?

别来无恙 提交于 2019-11-29 13:15:28

If you take a look at my post actually I have a solution for join

@Override
public Specification<User> getFilter(UserListRequest request) {
    return (root, query, cb) -> {
        query.distinct(true); //Important because of the join in the addressAttribute specifications
        return where(
            where(firstNameContains(request.search))
                .or(lastNameContains(request.search))
                .or(emailContains(request.search))
        )
            .and(streetContains(request.street))
            .and(cityContains(request.city))
            .toPredicate(root, query, cb);
    };
}

private Specification<User> firstNameContains(String firstName) {
    return userAttributeContains("firstName", firstName);
}

private Specification<User> lastNameContains(String lastName) {
    return userAttributeContains("lastName", lastName);
}

private Specification<User> emailContains(String email) {
    return userAttributeContains("email", email);
}

private Specification<User> userAttributeContains(String attribute, String value) {
    return (root, query, cb) -> {
        if(value == null) {
            return null;
        }

        return cb.like(
            cb.lower(root.get(attribute)),
            containsLowerCase(value)
        );
    };
}

private Specification<User> cityContains(String city) {
    return addressAttributeContains("city", city);
}

private Specification<User> streetContains(String street) {
    return addressAttributeContains("street", street);
}

private Specification<User> addressAttributeContains(String attribute, String value) {
    return (root, query, cb) -> {
        if(value == null) {
            return null;
        }

        ListJoin<User, Address> addresses = root.joinList("addresses", JoinType.INNER);

        return cb.like(
            cb.lower(addresses.get(attribute)),
            containsLowerCase(value)
        );
    };
}

private String containsLowerCase(String searchField) {
    return "%" + searchField.toLowerCase() + "%";
}

Here you can see how I search the users by their address columns (city and street).

EDIT: Also you cannot use the @Query annotation that much dinamically (you van insert parameter values dinamically, but not parameters. That's where Specificaion is handy)

EDIT2: I know this is not the 2.x.x Spring version, but 1.5.x, but the idea is the same for joins.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!