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

后端 未结 1 718
情歌与酒
情歌与酒 2020-12-20 08:48

I am taking this question Perform multi column search on Date, Integer and String Data type fields of Single Table? and This method must return a result of type Specificatio

1条回答
  •  猫巷女王i
    2020-12-20 09:45

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

    @Override
    public Specification 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 firstNameContains(String firstName) {
        return userAttributeContains("firstName", firstName);
    }
    
    private Specification lastNameContains(String lastName) {
        return userAttributeContains("lastName", lastName);
    }
    
    private Specification emailContains(String email) {
        return userAttributeContains("email", email);
    }
    
    private Specification 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 cityContains(String city) {
        return addressAttributeContains("city", city);
    }
    
    private Specification streetContains(String street) {
        return addressAttributeContains("street", street);
    }
    
    private Specification addressAttributeContains(String attribute, String value) {
        return (root, query, cb) -> {
            if(value == null) {
                return null;
            }
    
            ListJoin 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.

    0 讨论(0)
提交回复
热议问题