程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了带有任意AND子句的动态Spring Data JPA存储库查询大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决带有任意AND子句的动态Spring Data JPA存储库查询?

开发过程中遇到带有任意AND子句的动态Spring Data JPA存储库查询的问题如何解决?下面主要结合日常开发的经验,给出你关于带有任意AND子句的动态Spring Data JPA存储库查询的解决方法建议,希望对你解决带有任意AND子句的动态Spring Data JPA存储库查询有所启发或帮助;

请注意,使用新的主要版本的queryDSL(4.x)和querydsl-jpa可能需要进行一些更改。

在我们的项目之一,我们用queryDSL@H_607_6@用queryDslPreDicateExecutor<T>@H_607_6@。

  public PreDicate createPreDicate(DataEntity dataEntity) {
    QDataEntity qDataEntity = QDataEntity.dataEntity;
    BooleanBuilder BooleanBuilder = new BooleanBuilder();
    if (!StringUtils.isEmpty(dataEntity.getCnsiConsumerNo())) {
      BooleanBuilder
        .or(qDataEntity.cnsiConsumerNo.contains(dataEntity.getCnsiConsumerNo()));
    }
    if (!StringUtils.isEmpty(dataEntity.getCnsiMeterNo())) {
      BooleanBuilder.or(qDataEntity.cnsiMeterNo.contains(dataEntity.getCnsiMeterNo()));
    }

    return BooleanBuilder.getValue();
  }
@H_607_6@

我们可以在存储库中使用它:

@Repository
public interface DataEntityRepository
  extends DaoRepository<DataEntity, Long> {
@H_607_6@

哪里DaoRepository是

@norepositoryBean
public interface DaoRepository<T, K extends serializable>
  extends JpaRepository<T, K>,
  queryDslPreDicateExecutor<T> {
}
@H_607_6@

因为这样,你可以使用存储库谓词方法。

Iterable<DataEntity> results = dataEntityRepository.findAll(dataEntityPreDicateCreator.createPreDicate(dataEntity));
@H_607_6@

要获取QClasses,你需要在pom.xml中指定queryDSL APT Maven插件。

  <build>
    <plugins>
      <plugin>
        <groupID>com.mysema.maven</groupID>
        <artifactID>maven-apt-plugin</artifactID>
        <version>1.0.4</version>
        <EXECUTIONS>
          <execution>
            <phase>generate-sources</phase>
            <goals>
              <goal>process</goal>
            </goals>
            <configuration>
              <outputDirectory>target/generated-sources</outputDirectory>
              <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
            </configuration>
          </execution>
        </EXECUTIONS>
      </plugin>
@H_607_6@

依赖项是

    <!-- querydsl -->
    <dependency>
        <groupID>com.mysema.querydsl</groupID>
        <artifactID>querydsl-core</artifactID>
        <version>${querydsl.version}</version>
    </dependency>
    <dependency>
        <groupID>com.mysema.querydsl</groupID>
        <artifactID>querydsl-apt</artifactID>
        <version>${querydsl.version}</version>
    </dependency>
    <dependency>
        <groupID>com.mysema.querydsl</groupID>
        <artifactID>querydsl-jpa</artifactID>
        <version>${querydsl.version}</version>
    </dependency>
@H_607_6@

或对于Gradle:

sourceSets {
    generated
}
sourceSets.generated.java.srcDirs = ['src/main/generated']
configurations {
    querydslapt
}
dependencIEs {
    // other deps ....
    compile "com.mysema.querydsl:querydsl-jpa:3.6.3"
    compile "com.mysema.querydsl:querydsl-apt:3.6.3:jpa"
}
task generatequeryDSL(type: JavaCompile, group: 'build', description: 'Generates the queryDSL query types') {
    source = sourceSets.main.java
    classpath = configurations.compile + configurations.querydslapt
    options.compilerArgs = [
            "-proc:only",
            "-processor", "com.mysema.query.apt.jpa.JPAAnnotationProcessor"
    ]
    desTinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}

compileJava {
    dependsOn generatequeryDSL
    source generatequeryDSl.desTinationDir
}

compileGeneratedJava {
    dependsOn generatequeryDSL
    classpath += sourceSets.main.runtimeClasspath
}
@H_607_6@

你可以使用Spring-data为你提供的即用型规范。并能够使用标准API以编程方式构建查询。要支持规范,你可以使用JpaSpecificationExecutor接口扩展存储库接口

public interface CustomerRepository extends SimpleJpaRepository<T, ID>, JpaSpecificationExecutor {

}
@H_607_6@

附加接口(JpaSpecificationExecutor)包含允许你以多种方式执行Specification的方法。

例如,findAll方法将返回与规范匹配的所有实体:

List<T> findAll(Specification<T> spec);
@H_607_6@

规范界面如下:

public interface Specification<T> {
     PreDicate topreDicate(Root<T> root, Criteriaquery<?> query,
            CriteriaBuilder builder);
}
@H_607_6@

好的,那么典型的用例是什么?规范可以轻松地用于在实体之上构建可扩展的谓词集,然后可以将其与JpaRepository组合并使用,而无需为每个所需的组合声明查询(方法)。这是一个示例:示例2.15。客户规格

public class CustomerSpecs {
    public static Specification<Customer> isLongTermCustomer() {
        return new Specification<Customer>() {
            public PreDicate topreDicate(
                Root<Customer> root, Criteriaquery<?> query,
                CriteriaBuilder builder) {
                LocalDate date = new LocalDate().minusYears(2);
                return builder.lessthan(root.get('dateFIEld'), datE);
            }
        };
    }

    public static Specification<Customer> hasSALEsOfMoreThan(Montaryamount value) {
        return new Specification<Customer>() {
            public PreDicate topreDicate(
                Root<T> root, Criteriaquery<?> query,
                CriteriaBuilder builder) {
                // build query here
            }
        };
    }
}
@H_607_6@

你在业务需求抽象级别上表达了一些标准,并创建了可执行的规范。因此,客户端可以使用以下规范:

List customers = customerRepository.findAll(isLongTermCustomer());
@H_607_6@

你还可以结合规范示例2.17。组合规格

    Monetaryamount amount = new Monetaryamount(200.0, CurrencIEs.DolLAR);
    List<Customer> customers = customerRepository.findAll(
        where(isLongTermCustomer()).or(hasSALEsOfMoreThan(amount)));
@H_607_6@

如你所见,规范提供了一些粘合代码方法来链接和组合规范。因此,扩展数据访问层只是创建新的规范实现并将它们与现有的实现结合在一起的问题。

可以创建复杂的规格,这是一个示例

public class WorkInProgressspecification {
    public static Specification<WorkInProgress> findByCriteria(final SearchCriteria searchCriteria) {

        return new Specification<WorkInProgress>() {

            @OverrIDe
            public PreDicate topreDicate(
                Root<WorkInProgress> root,
                Criteriaquery<?> query, CriteriaBuilder cb) {

                List<PreDicate> preDicates = new ArrayList<PreDicate>();

                if (searchCriteria.getVIEw() != null && !searchCriteria.getVIEw().isEmpty()) {
                    preDicates.add(cb.equal(root.get("vIEwType"), searchCriteria.getVIEw()));
                }
                if (searchCriteria.getFeature() != null && !searchCriteria.getFeature().isEmpty()) {
                    preDicates.add(cb.equal(root.get("title"), searchCriteria.getFeature()));
                }
                if (searchCriteria.getEpic() != null && !searchCriteria.getEpic().isEmpty()) {
                    preDicates.add(cb.equal(root.get("epic"), searchCriteria.getEpic()));
                }
                if (searchCriteria.getPerformingGroup() != null && !searchCriteria.getPerformingGroup().isEmpty()) {
                    preDicates.add(cb.equal(root.get("performingGroup"), searchCriteria.getPerformingGroup()));
                }
                if (searchCriteria.getPlAnnedStartDate() != null) {
                    System.out.println("searchCriteria.getPlAnnedStartDate():" + searchCriteria.getPlAnnedStartDate());
                    preDicates.add(cb.greaterThanorequalTo(root.<Date>get("plndStartDate"), searchCriteria.getPlAnnedStartDate()));
                }
                if (searchCriteria.getPlAnnedCompletionDate() != null) {
                    preDicates.add(cb.lessthanorequalTo(root.<Date>get("plndComplDate"), searchCriteria.getPlAnnedCompletionDate()));
                }
                if (searchCriteria.getTeam() != null && !searchCriteria.getTeam().isEmpty()) {
                    preDicates.add(cb.equal(root.get("agileTeam"), searchCriteria.getTeam()));
                }

                return cb.and(preDicates.toArray(new PreDicate[] {}));
            }
        };
    }
}
@H_607_6@

解决方法

我正在使用Spring data jpa repositories@H_607_6@,要求提供具有不同字段的搜索功能。搜索之前输入的字段是optional.I有5场说employeenumber,Name,Married,Profession和DateOfBirth@H_607_6@。
在这里我只需要查询用户给定的值,其他字段应该被忽略。

Input : employeenumber:,Name:St,Married:,Professsion:IT,DateOfBirth: 
Query : SELEct * from employee e where Name like 'St%' and Profession like 'IT%';  

Input : employeenumber:10,Name:,DateOfBirth:
Query : SELEct * from employee e where employeenumber like '10%' and Profession like 'IT%';  
@H_607_6@

因此,这里我们虑输入的值和进行查询。在这种情况下,Spring数据是具有限制中提到的这篇文章(不可扩展,所有可能出现的问题,应书面)我使用的Querydsl@H_607_6@,但仍然存在问题的null@H_607_6@领域应该被忽视,需要开发的几乎所有可能出现的问题。在这case 31 queries@H_607_6@。如果搜索字段是6,7,8...@H_607_6@?

用可选字段实现搜索选项的最佳方法是什么?

大佬总结

以上是大佬教程为你收集整理的带有任意AND子句的动态Spring Data JPA存储库查询全部内容,希望文章能够帮你解决带有任意AND子句的动态Spring Data JPA存储库查询所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。