Spring数据JPA自定义存储库,如何应用逻辑 [英] Spring data JPA custom repository, how apply logic

查看:26
本文介绍了Spring数据JPA自定义存储库,如何应用逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I try to implement a JPA custom repository.

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

I have a filter object like this:

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

    ... and so on
}

从前端,我根据用户输入创建了一个 FilterPatient 实例.

From front end I create an instance of FilterPatient based on user input.

因此,例如,用户可以对 surname 和 cf 属性或 surname 和 name 等进行赋值

So, user, for example, can value surname and cf properties or surname and name, and so on

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

I want to implement a custom repository as follow:

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
}

问题:

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

Based on user input I must execute a different query, so how I manage the repository? I must write query methods to cover different combinations of input field and in the service I must write the logic about method repository call? Or I can parametrize better my custom method query?

其他信息:

通常没有spring-data,我定义了一个带有输入参数FilterPatient的DAO方法,所以我基于参数非空构建了一个查询,然后我用query.setString方法.这样我写了一个通用方法,是否可以使用 Spring-data 和 JPA 存储库?

Without spring-data normally, I define a DAO method with input parameter FilterPatient, so I build a query based on parameter not null and then I substitute parameter with query.setString method. In this way I write one generic method, is it possible with Spring-data and JPA repositories?

编辑

用户查询示例

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

以及其他可能的配置,例如在FilterPatient的cf属性中,查询为:

and other possible configuration, for example, in cf property of FilterPatient IS NULL, the query will become:

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

推荐答案

您正在寻找的是规范模式,该模式在以下与 Spring Data JPA 相关:

What you are looking for is the Specification pattern which is discussed in relation to Spring Data JPA at the following:

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

以及每个查询都有一个查询方法的注释:

and which notes with reference to having a query method per query:

虽然这种方法真的很方便(你甚至不必编写一行实现代码来获取查询执行)它有两个缺点:第一,查询方法的数量可能会因更大的应用程序而增长 - 这是第二个点 - 查询定义了一组固定的标准.为了避免这些两个缺点,如果你能想出一套是不是很酷您可以动态组合以构建您的原子谓词查询?

Although this approach is really convenient (you don’t even have to write a single line of implementation code to get the queries executed) it has two drawbacks: first, the number of query methods might grow for larger applications because of - and that’s the second point - the queries define a fixed set of criterias. To avoid these two drawbacks, wouldn’t it be cool if you could come up with a set of atomic predicates that you could combine dynamically to build your query?

您可以使用 JPA 标准 API 或使用 QueryDSL 来实现规范模式.使用后者就像让您的存储库扩展以下界面一样简单:

You can implement the Specification pattern using either the JPA criteria API or using QueryDSL. Using the latter this is as easy as having your repository extend the following interface:

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

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

and adding support for Querydsl to your project. For a Maven project you simply need to add the configuration below to your POM. The plugin will auto generate the Query classes required to construct the predicates and you can then call the following methods of your Repository with any combination of parameters:

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 就变得简单了:

With this approach then your PatientRepository becomes simply:

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

请注意,Spring Data Gosling 版本还增加了对自动将 HTTP 参数绑定到 QueryDSL Predicate 的支持,因此您还可以删除过滤器并让 Spring Data 端到端处理所有内容.

Note that the Spring Data Gosling release also added support for automatically binding HTTP params to a QueryDSL Predicate so you could also remove your Filter and have Spring Data handle everything end-to-end.

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

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

There are some examples here showing 1 query method being called with various parameters:

https://stackoverflow.com/a/26450224/1356423

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>

这篇关于Spring数据JPA自定义存储库,如何应用逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆