当前位置: 首页 > 面试题库 >

Spring Data JPA自定义存储库,如何应用逻辑

巫新知
2023-03-14
问题内容

我尝试实现JPA自定义存储库。

我有一个这样的过滤器对象:

public class FilterPatient {
    private String surname;
    private String name;
    private String cf;

    ... and so on
}

前端,我根据用户输入创建FilterPatient的实例。

因此,例如,用户可以值姓和cf属性或值和姓,等等。

我想实现一个自定义存储库,如下所示:

PatientRepository extends JpaRepository<Patient, Long> {
    List<Patient> findBySurname(String surname);

    List<Patient> findByName(String name);

    List<Patient> findByCf(String cf);

    // custom methods:
    @Query("select p from Patient p where p.name = :name
        and p.surname = :surname")
    List<Patient> findByNameAndSurname(@Param("name") String name,
          @Param("surname") String surname);

    ... and so on
}

题:

根据用户输入,我必须执行其他查询,那么如何管理存储库?我必须编写查询方法以涵盖输入字段的不同组合,并且必须在服务中编写有关方法存储库调用的逻辑?或者我可以更好地自定义方法查询参数化?

其他信息:

通常,在没有spring-
data的情况下,我使用输入参数定义了DAO方法FilterPatient,因此我基于不为null的参数构建查询,然后用query.setString方法替换参数。通过这种方式,我编写了一个通用方法,Spring-
data和JPA存储库是否可能?

编辑

用户查询示例

SELECT FROM Patient p WHERE p.name = :name
AND p.surname = :surname
AND p.cf = :cf

和其他可能的配置,例如,在FilterPatient IS NULL的cf属性中,查询将变为:

SELECT FROM Patient p WHERE p.name = :name
AND p.surname = :surname

问题答案:

您正在寻找的是规范模式,以下将与Spring Data JPA进行讨论:

https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-
and-querydsl/

以及关于每个查询具有查询方法的说明:

尽管这种方法确实很方便(您甚至不必编写一行实现代码即可执行查询),但它有两个缺点:首先,由于-,对于较大的应用程序,查询方法的数量可能会增加。第二点-
查询定义了一组固定的条件。为避免这两个缺点,如果您能提出一组可以动态组合以构建查询的原子谓词,这不是很酷吗?

您可以使用JPA标准API或QueryDSL来实现规范模式。使用后者,就像让您的存储库扩展以下接口一样容易:

http://docs.spring.io/spring-
data/commons/docs/current/api/org/springframework/data/querydsl/QueryDslPredicateExecutor.html

并将对Querydsl的支持添加到您的项目中。对于Maven项目,您只需要将以下配置添加到POM。该插件将自动生成构造谓词所需的Query类,然后您可以使用任何参数组合调用存储库的以下方法:

Iterable<T> findAll(com.querydsl.core.types.OrderSpecifier<?>... orders)
Iterable<T> findAll(com.querydsl.core.types.Predicate predicate)
Iterable<T> findAll(com.querydsl.core.types.Predicate predicate, com.querydsl.core.types.OrderSpecifier<?>... orders)
Page<T> findAll(com.querydsl.core.types.Predicate predicate, Pageable pageable)
Iterable<T> findAll(com.querydsl.core.types.Predicate predicate, Sort sort)
T   findOne(com.querydsl.core.types.Predicate predicate)

使用这种方法,您的PatientRepository就会变得简单:

PatientRepository extends JpaRepository<Patient, Long>, QueryDslLPredicateExecutor<Patient> {
   // no query methods needed
}

请注意,Spring Data
Gosling发行版还添加了对将HTTP参数自动绑定到QueryDSL谓词的支持,因此您还可以删除Filter并让Spring Data端到端处理所有内容。

https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-
gosling#querydsl-web-support

这里有一些示例显示了使用各种参数调用一种查询方法:

http://codingdict.com/questions/54783

Maven设置:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    .....

    <properties>
        <querydsl.version>4.1.3</querydsl.version>
    </properties>

    <dependencies>

        .....

        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>${querydsl.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>

           ....

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>


 类似资料:
  • 我尝试实现一个JPA自定义存储库。 我有一个过滤器对象,如下所示: 在前端,我根据用户输入创建了一个FilterPatient实例。 按用户分类的示例查询 和其他可能的配置,例如,在FilterPatient的cf属性为NULL中,查询将变为:

  • 在我的项目中有几个实体具有相同的属性(对于示例'name'),所以,有可能创建一个存储库,其中使用自定义的select(实体)?因此,我从JpaRepository扩展了我的存储库,我扩展了MyCustomJpaRepository,MyCustomJpaRepository也扩展了JpaRepository,使其能够从JpaRepository授予基本功能? TKS

  • 我有一个实体类称为和一个仓库声明如下: 自定义存储库的定义如下: 和 下面是另一个堆栈溢出问题中描述的内容:如何向Spring数据JPA添加自定义方法 现在,IntelliJ给了我一个警告: 我尝试将这些注释添加到中,但没有一个成功: 但都不管用。显然有些是错的,但我在试验。正确的注释是什么。 使用,我得到了以下错误:

  • 我发现对于减少样板非常有用,但它似乎给工作带来了麻烦。我现在试图用自定义的基类存储库扩展,而在启动时,Spring在正确实例化存储库方面遇到了问题。 我已经尝试了几个关于这个主题的变体,但是没有运气让事情成功地连线起来。我在Spring的问题跟踪器https://jira.spring.io/browse/datajpa-674上遇到了一个类似的问题,但没有关于修复的解释,只是对代码进行了重构,使

  • 我最终不得不在文件。定义通常非常繁琐: 注意上面gradle提供了一种定义常用maven存储库的好方法(即)。我想在插件或父gradle脚本中找到一种方法,在函数中或静态地定义存储库,然后在块中调用它:。 我缺乏groovy方面的知识,因此我不太了解解析groovy源代码所需的知识,我正在寻找一种很好的方法来实现这一点。我该怎么做? 我知道在父级gradle文件中,我可以使用或。我不想将这些mav

  • 如果你需要提供自定义文件存储 – 一个普遍的例子是在某个远程系统上储存文件 – 你可以通过定义一个自定义的储存类来实现。你需要遵循以下步骤: 1. 你的自定义储存类必须是django.core.files.storage.Storage的子类: from django.core.files.storage import Storage class MyStorage(Storage):