简体   繁体   English

如何根据spring数据jpa中的条件指定append

[英]How to append specification based on condition in spring data jpa

I am creating a spring boot project and working on spring data jpa and currently I am using custom query to fetch data from db based on users selection and this is my page where user can select option based on their condition https://i.imgur.com/coO3BCJ.png我正在创建一个 spring 引导项目并处理 spring 数据 jpa,目前我正在使用自定义查询根据用户选择从数据库中获取数据,这是我的页面,用户可以根据自己的条件 select 选项https://i.imgur .com/coO3BCJ.png

So, I googled it and found we can use specification but as I am very new to specification, so, I used specification and I want that based on users choice, it should keep adding specification, so, this is my conditional specification...所以,我在谷歌上搜索了一下,发现我们可以使用规范,但由于我对规范很陌生,所以,我使用了规范,我希望根据用户的选择,它应该不断添加规范,所以,这是我的条件规范......

Specification<UserDetails> specification = 
Specification.where(UserDetailsSpecification
.isAgeBetween(customSearch.getFromage(), customSearch.getToage()));

if(!customSearch.getManglik().isBlank()) {               
 specification.and(UserDetailsSpecification.isManglik
 (customSearch.getManglik())); 
}
if(!customSearch.getMaritalStatus().isBlank()) {                 
specification.and(UserDetailsSpecification
.hasMaritalStatus(customSearch.getMaritalStatus())); 
}
if(!customSearch.getReligion().isBlank()) {              
specification.and(UserDetailsSpecification.hasReligion
(customSearch.getReligion())); 
}
if(!customSearch.getCaste().isBlank()) {                 
specification.and(UserDetailsSpecification.hasCaste
(customSearch.getCaste())); 
}
  if(!customSearch.getLocation().isBlank()) {                
  specification.and(UserDetailsSpecification.hasLocation
(customSearch.getLocation())); 
}

listOfCustomSearch=userDetailsRepository
.findAll(specification, pageable);
List<UserDetails> listOfAllSearchedUsers = listOfCustomSearch.getContent();

but it is not appending the specification and just filtering the data based on only但它没有附加规范,只是根据仅过滤数据

Specification<UserDetails> specification = Specification.where(UserDetailsSpecification
                .isAgeBetween(customSearch.getFromage(), customSearch.getToage()));

so, based on users selection, so, my final query should be something like this(If user has selected all fields):所以,基于用户的选择,所以,我的最终查询应该是这样的(如果用户选择了所有字段):

Specification<UserDetails> specification = Specification.where(UserDetailsSpecification
.isAgeBetween(customSearch.getFromage(), customSearch.getToage())
.and(UserDetailsSpecification.isManglik(customSearch.getManglik())                  .and(UserDetailsSpecification.hasMaritalStatus(customSearch.getMaritalStatus()))                    .and(UserDetailsSpecification.hasReligion(customSearch.getReligion()))
.and(UserDetailsSpecification.hasCaste(customSearch.getCaste()))
.and(UserDetailsSpecification.hasLocation(customSearch.getLocation()))))

But suppose if user has selected only let suppose 3 or 4 fields, so, my final specification should be something like below:(This specification should be completely depends upon user selection)但是假设如果用户只选择了 3 或 4 个字段,那么,我的最终规范应该如下所示:(这个规范应该完全取决于用户的选择)

Specification<UserDetails> specification = Specification.where(UserDetailsSpecification
.isAgeBetween(customSearch.getFromage(), customSearch.getToage())
.and(UserDetailsSpecification.isManglik(customSearch.getManglik())                  
.and(UserDetailsSpecification.hasLocation(customSearch.getLocation()))))

Currently it is not appending specification based on users selection, so, please help me in adding specification based on users selections目前它没有根据用户选择添加规范,所以,请帮助我根据用户选择添加规范

Finally, I found the solution and we can create customized specification like this below:最后,我找到了解决方案,我们可以像下面这样创建自定义规范:

public static Specification<UserDetails> getSpecs(String gender, int fromAge, int toAge, String manglikStatus, String maritalStatus, String religion, String caste, String location){
    Specification<UserDetails> spec = null;
    Specification<UserDetails> temp = null;
    
    if(!gender.isBlank() && !gender.isEmpty() && gender!=null && !gender.contains("$")) {
        spec = getSpecsForGenderDetails(gender);
        temp = spec!=null?Specification.where(spec).and(temp):temp; 
    }
    
    if(fromAge!=0 || toAge!=0) {
        spec = isAgeBetween(fromAge, toAge);
        temp = spec!=null?Specification.where(spec).and(temp):temp;
    }
    if(!manglikStatus.isBlank() && !manglikStatus.isEmpty() && manglikStatus!=null && !manglikStatus.contains("$")) {
        spec = isManglik(manglikStatus);
        temp = spec!=null?Specification.where(spec).and(temp):temp; 
    }
    if(!maritalStatus.isBlank() && !maritalStatus.isEmpty() && maritalStatus!=null && !maritalStatus.contains("$")) {
        spec = hasMaritalStatus(maritalStatus);
        temp = spec!=null?Specification.where(spec).and(temp):temp; 
    }
    if(!religion.isBlank() && !religion.isEmpty() && religion!=null && !religion.contains("$")) {
        spec = hasReligion(religion);
        temp = spec!=null?Specification.where(spec).and(temp):temp; 
    }
    if(!caste.isBlank() && !caste.isEmpty() && caste!=null && !caste.equalsIgnoreCase("select") && !caste.contains("$")) {
        spec = hasCaste(caste);
        temp = spec!=null?Specification.where(spec).and(temp):temp; 
    }
    if(!location.isBlank() && !location.isEmpty() && location!=null && !location.contains("$")) {
        spec = hasLocation(location);
        temp = spec!=null?Specification.where(spec).and(temp):temp; 
    }
    return temp;
    
}

And based on that we can define our method like this:基于此,我们可以这样定义我们的方法:

private static Specification<UserDetails> getSpecsForGenderDetails(String gender) {
    return ((root, query, criteriaBuilder) -> {
        return criteriaBuilder.equal(root.get("gender"),gender);
    });
}

private static Specification<UserDetails> isAgeBetween(int fromAge, int toAge){
    return ((root, query, criteriaBuilder) -> {
        return criteriaBuilder.between(root.get("age"), fromAge, toAge);
    });
}

private static Specification<UserDetails> isManglik(String manglikStatus){
    return ((root, query, criteriaBuilder) -> {
        return criteriaBuilder.like(criteriaBuilder.lower(root.get("manglikStatus")),"%" +manglikStatus.toLowerCase() +"%");            
    });
}

private static Specification<UserDetails> hasMaritalStatus(String maritalStatus){
    return ((root, query, criteriaBuilder) -> {
        return criteriaBuilder.like(criteriaBuilder.lower(root.get("maritalStatus")),"%" +maritalStatus.toLowerCase() +"%");            
    });
}
private static Specification<UserDetails> hasReligion(String religion){
    return ((root, query, criteriaBuilder) -> {
        return criteriaBuilder.like(criteriaBuilder.lower(root.get("religion")),"%" +religion.toLowerCase() +"%");
    });
}
private static Specification<UserDetails> hasCaste(String caste){
    return ((root, query, criteriaBuilder) -> {
        return criteriaBuilder.like(criteriaBuilder.lower(root.get("caste")),"%" +caste.toLowerCase() +"%");
    });
}
private static Specification<UserDetails> hasLocation(String presentState){
    return ((root, query, criteriaBuilder) -> {
        return criteriaBuilder.like(criteriaBuilder.lower(root.get("presentState")),"%" +presentState.toLowerCase() +"%");
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM