当前位置: 首页 > 知识库问答 >
问题:

specification.where().和()在Spring规范查询中的意外行为?

严恩
2023-03-14

我试图在Spring Boot中按规范在query中跨多个属性执行搜索。当我输入一个单词要搜索时,它可以工作,但当我输入两个单词时,它不能提供正确的输出。

这是模型。

@Entity
@NoArgsConstructor
@Getter
@Setter
public class Person {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_ID")
    private long id;
    
    private String firstName;
    
    private String surName;
    
    private int age;
    
    private Date dob;
    
    private String description;
    
    private String highestEducationQualification;
    
    private String occupation;
    
    private String employer;
    
    private String college;
    
    private String school;
    
    private String eyecolor;
    
    private double weight;
    
    private double height;
    
    private boolean driversLicence;
    
    private boolean provisionalLicence;

    private long phoneNumber;
    
    private char gender;
    
    private String emailAddress;
    
    private String websiteAddress;
    
    private String homeAddress;
    
    private String image;
    
}

@Repository
public interface PersonRepo extends JpaRepository<Person, Long>, JpaSpecificationExecutor<Person> {
    List<Person> searchByFirstNameContainingOrSurNameContainingAllIgnoreCase(String firstName, String surName);
    
    Person findByFirstName(String firstName);
    List<Person> searchByFirstNameContainingAllIgnoreCase(String firstName, Pageable page);
    List<Person> searchBySurNameContainingAllIgnoreCase(String surName, Pageable page);
    List<Person> searchByAge(int age, Pageable page);
    List<Person> searchByDescriptionContainingAllIgnoreCase(String desc, Pageable page);
    List<Person> searchByHighestEducationQualificationContainingAllIgnoreCase(String edu, Pageable page);
    List<Person> searchByOccupationContainingAllIgnoreCase(String occ, Pageable page);
    List<Person> searchByEmployerContainingAllIgnoreCase(String emp, Pageable page);
    List<Person> searchByCollegeContainingAllIgnoreCase(String emp, Pageable page);
    List<Person> searchBySchoolContainingAllIgnoreCase(String emp, Pageable page);
    List<Person> searchByEyecolorContainingAllIgnoreCase(String eye, Pageable page);
    List<Person> searchByWeight(double weight, Pageable page);
    List<Person> searchByHeight(double height, Pageable page);
    List<Person> searchByDriversLicence(boolean emp, Pageable page);
    List<Person> searchByProvisionalLicence(boolean emp, Pageable page);
    List<Person> searchByPhoneNumber(long phone, Pageable page);
    List<Person> searchByGender(char emp, Pageable page);
    List<Person> searchByEmailAddressIgnoreCase(String emp, Pageable page);
    List<Person> searchByWebsiteAddressContainingAllIgnoreCase(String emp, Pageable page);
    List<Person> searchByHomeAddressContainingAllIgnoreCase(String emp, Pageable page);
}
public List<Person> searchBySpecAll(String search, String page, String num, String sortBy, String ascending){
        ArrayList<PersonSpecification> personSpecs = new ArrayList<PersonSpecification>();
        
        ArrayList<String> searchWords = new ArrayList<String>();
        
        for(String s : search.split(" ")) {
            searchWords.add(s);
        }
        
        int numWords = searchWords.size();
        
        System.out.println("num words");
        
        
        for(String s : searchWords) {
            System.out.println(s);
            
            int age = 0;
            
             try {
                 age = Integer.parseInt(s);
             } catch (Exception e) {
                 
             }
             double d = 0;
             try {
                 d = Double.parseDouble(s);
             } catch (Exception e) {
                 
             }
             
            
             char gender = 0;
             try {
                 gender = search.charAt(0);
             } catch (Exception e) {
                 
             }
             
             
             PersonSpecification spec = new PersonSpecification(new SearchCriteria("firstName", ":", s));
             PersonSpecification spec2 = new PersonSpecification(new SearchCriteria("surName", ":", s));
             PersonSpecification spec3 = new PersonSpecification(new SearchCriteria("age", ":", age));
             PersonSpecification spec4 = new PersonSpecification(new SearchCriteria("description", ":", s));
             PersonSpecification spec5 = new PersonSpecification(new SearchCriteria("highestEducationQualification", "=", s));
             PersonSpecification spec6 = new PersonSpecification(new SearchCriteria("occupation", ":", s));
             PersonSpecification spec7 = new PersonSpecification(new SearchCriteria("employer", ":", s));
             PersonSpecification spec8 = new PersonSpecification(new SearchCriteria("college", ":", s));
             PersonSpecification spec9 = new PersonSpecification(new SearchCriteria("school", ":", s));
             PersonSpecification spec10 = new PersonSpecification(new SearchCriteria("eyecolor", "=", s));
             PersonSpecification spec11 = new PersonSpecification(new SearchCriteria("weight", "=", d));
             PersonSpecification spec12 = new PersonSpecification(new SearchCriteria("height", "=", d));
             PersonSpecification spec17 = new PersonSpecification(new SearchCriteria("phoneNumber", "=", d));
             //PersonSpecification spec18 = new PersonSpecification(new SearchCriteria("gender", "=", gender));
             PersonSpecification spec19 = new PersonSpecification(new SearchCriteria("emailAddress", "=", s));
             PersonSpecification spec20 = new PersonSpecification(new SearchCriteria("websiteAddress", ":", s));
             PersonSpecification spec21 = new PersonSpecification(new SearchCriteria("homeAddress", ":", s));;
             
             personSpecs.add(spec);
             personSpecs.add(spec2);
             personSpecs.add(spec3);
             //personSpecs.add(spec4);
             //personSpecs.add(spec5);
             personSpecs.add(spec6);
             personSpecs.add(spec7);
             personSpecs.add(spec8);
             personSpecs.add(spec9);
             personSpecs.add(spec10);
             personSpecs.add(spec11);
             personSpecs.add(spec12);
             personSpecs.add(spec17);
             //personSpecs.add(spec18);
             personSpecs.add(spec19);
             personSpecs.add(spec20);
             personSpecs.add(spec21);
        }
        
         int pageNum = 0;
         try {
             pageNum = Integer.parseInt(page);
         } catch (Exception e) {
             
         }
         
         int numResults = 0;
         try {
             numResults = Integer.parseInt(num);
         } catch (Exception e) {
             
         }
         boolean asc = true;
         if(ascending.equals("false"))
             asc = false;
         
        
        Pageable firstPageWithFourElements = PageRequest.of(pageNum, numResults, Sort.by(Sort.Direction.DESC, sortBy));;
        
         if(asc) {
             firstPageWithFourElements = PageRequest.of(pageNum, numResults, Sort.by(Sort.Direction.ASC, sortBy));
         } 
         
         ArrayList<Specification<Person>> specs = new ArrayList<Specification<Person>>();
         
         Specification<Person> specTotal = null;
         
         int numSpecs = 14;
         
         int iters = personSpecs.size() / numSpecs; 
         
         System.out.println(personSpecs.size());
         
         System.out.println("Iterations of personSpecs: " + iters);
        
         
         for(int i = 0; i < iters; i++) {
             specs.add(Specification.where(personSpecs.get(i)).or(personSpecs.get(i + 1)).or(personSpecs.get(i + 2)).or(personSpecs.get(i + 3)).or(personSpecs.get(i + 4)).or(personSpecs.get(i + 5)).or(personSpecs.get(i + 6)).or(personSpecs.get(i + 7)).or(personSpecs.get(i + 8)).or(personSpecs.get(i + 9)).or(personSpecs.get(i + 10)).or(personSpecs.get(i + 11)).or(personSpecs.get(i + 12)).or(personSpecs.get(i + 13)));
         }
         System.out.println("Number of specifications to append to total: " + specs.size());
         
         int totalToAppend = 0;
         totalToAppend = specs.size();
         
         System.out.print(totalToAppend);
         
         switch(totalToAppend) {
            case 1: {
                specTotal = specs.get(0); 
                System.out.println(1 + " case");
                break;
            }
            case 2: {
                specTotal = Specification.where(specs.get(0).and(specs.get(1))); 
                break;
            }
            case 3: {
                specTotal = Specification.where(specs.get(0).and(specs.get(1)).and(specs.get(2)));  
                break;
            }
            case 4: {
                specTotal = Specification.where(specs.get(0).and(specs.get(1)).and(specs.get(2)).and(specs.get(3)));  
                break;
            }
         }
         
         //specTotal = Specification.where(spec).or(spec2).or(spec3).or(spec6).or(spec7).or(spec8).or(spec9).or(spec11).or(spec12).or(spec19).or(spec21).or(spec20).or(spec4).or(spec5).or(spec10).or(spec17);
         
         Page<Person> results = personRepo.findAll(specTotal, firstPageWithFourElements);
        
        
         List<Person> res = results.getContent();
         
         return res;
    }

下面是生成的SQL。

Hibernate: select person0_.user_id as user_id1_0_, person0_.age as age2_0_, person0_.college as college3_0_, person0_.description as descript4_0_, person0_.dob as dob5_0_, person0_.drivers_licence as drivers_6_0_, person0_.email_address as email_ad7_0_, person0_.employer as employer8_0_, person0_.eyecolor as eyecolor9_0_, person0_.first_name as first_n10_0_, person0_.gender as gender11_0_, person0_.height as height12_0_, person0_.highest_education_qualification as highest13_0_, person0_.home_address as home_ad14_0_, person0_.image as image15_0_, person0_.occupation as occupat16_0_, person0_.phone_number as phone_n17_0_, person0_.provisional_licence as provisi18_0_, person0_.school as school19_0_, person0_.sur_name as sur_nam20_0_, person0_.website_address as website21_0_, person0_.weight as weight22_0_ from person person0_ where (person0_.first_name like ? or person0_.home_address like ? or person0_.website_address like ? or person0_.email_address=? or person0_.phone_number=0 or person0_.height=0.0 or person0_.weight=0.0 or person0_.eyecolor=? or person0_.school like ? or person0_.college like ? or person0_.employer like ? or person0_.occupation like ? or person0_.age=0 or person0_.sur_name like ?) and (person0_.home_address like ? or person0_.website_address like ? or person0_.email_address=? or person0_.phone_number=0 or person0_.height=0.0 or person0_.weight=0.0 or person0_.eyecolor=? or person0_.school like ? or person0_.college like ? or person0_.employer like ? or person0_.occupation like ? or person0_.age=0 or person0_.sur_name like ? or person0_.first_name like ?) order by person0_.first_name asc limit ?

我实际上希望搜索所有属性,有些属性是一个词,到文本段落。我希望搜索查询被分解成单词,这样它就可以通过名字和姓氏进行搜索,例如。

共有1个答案

方和豫
2023-03-14

我认为问题在于您添加了disjux,如person0_.weight=0.0,这对其他一些人来说是正确的。试着把这些移开。

 类似资料:
  • 有一个使用属性表达式的查询:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-方法。查询属性表达式: 试图通过规范执行查询: 我得到了一个错误: 我做错了什么或忘记添加了什么? 查询:按教师姓名显示所有学生 基地实体: 实体教师: 实体学生: 实体教室: 实体教室:

  • 我使用spring jpa规范动态构建实体查询。 它工作完美,但是查询返回所有实体字段,这使得性能变慢。我只想获取特定的实体字段,而不是获取我不想要也不会使用的所有实体字段和依赖项。 我在网上搜索,尝试了一些场景,但没有任何不足。有人能就此提出任何解决方案吗? 提前感谢 这是我的。我正在使用spring boot 2.2.4 规格: 存储库: 音乐会服务: ConcertServiceImpl:

  • 我正在使用一个JPA查询,它使用一个规范来检索实体。当我执行查询时,我得到了一个错误: 组织。springframework。数据映射。PropertyReferenceException:找不到类型任务的属性名称! 我已经查看了之前在该网站上提出的类似问题的答案 当我使用调试器逐步检查代码时,条件生成器中的扩展路径将返回嵌入的ID类,但当规范实际用于查询时,该属性似乎正在应用于基本实体类。 我是

  • 示例设置: 问题在于distinct和sort的结合。distinct要求发布服务器名称位于选择字段中,以便能够进行排序。 我如何用规范查询解决这个问题?

  • 我知道我们可以直接从左连接实现它,但由于一些限制,我们使用交叉连接,所以我需要走这条路... 请分享您的想法,欢迎提出建议 更新1我们没有使用关联,这就是为什么我们严格交叉连接。

  • 我有一个用spring boot Version1.5.x编写的项目,它连接到一个MariaDB数据库和几个表,它们之间有大量的关系。为了查询数据库,我使用org.springframework.data.jpa.repository中提供的JpaSpecificationExecutor接口。我们使用规范的原因是为了构建动态查询,而不必为存储库本身中的每个筛选可能性编写新的查询。在实体本身中,每