简体   繁体   English

如何在Spring数据JPA中动态select列

[英]How to dynamically select columns in Spring Data JPA

I have a typical Spring boot(2.7.6) application with apis' to fetch data in Kotlin .我有一个典型的 Spring boot(2.7.6) 应用程序,带有用于在Kotlin中获取数据的 api。

Assume an entity called Employee假设一个名为 Employee 的实体

@Entity
data class Employee(
val id: Long,
val name: String,
val age: Int,
val interviewDate: LocalDate,
val joiningDate: LocalDate,
val resignationDate: LocalDate,
val lastWorkingDate: LocalDate
)

For brevity I have removed annotations like @Id etc from above entity class.为简洁起见,我从上面的实体 class 中删除了@Id等注释。

One of the APIs which vends out Employee data is such that, in request params I get something like dateType and it will have one of interviewDate/joiningDate/resignationDate/lastWorkingDate .出售员工数据的 API 之一是这样的,在请求参数中我得到类似dateType的东西,它将具有interviewDate/joiningDate/resignationDate/lastWorkingDate And in request params dateFrom and dateTo , I get the date as an input like 2020-10-01 and 2022-12-30在请求参数dateFromdateTo中,我将日期作为输入,例如2020-10-012022-12-30

For example, if api gets input like dateType=interviewDate&dateFrom=2020-10-01&dateTo=2022-12-30 then API has to return all the employee records whose interview_date column has values between 2020-10-01 and 2022-12-30例如,如果 api 获得类似dateType=interviewDate&dateFrom=2020-10-01&dateTo=2022-12-30的输入,则 API 必须返回interview_date列的值介于2020-10-012022-12-30之间的所有员工记录

The example given above is just for ease of explaining.上面给出的示例只是为了便于说明。 For real use-case have to fetch data from many tables and has many joins(inner/left/right).对于实际用例,必须从许多表中获取数据并具有许多连接(内/左/右)。

Based on the input, what is the better way to select columns dynamically in repository method?根据输入,在存储库方法中动态 select 列的更好方法是什么?

I tried Specification Criteria API , but it was a dead end because I cannot use joins as there is no mapping between Entities like @OneToMany etc.我尝试了Specification Criteria API ,但这是一个死胡同,因为我不能使用joins ,因为实体之间没有映射,如@OneToMany等。

I am trying with @Query to get data but have to duplicate lots of lines of sql for each condition.我正在尝试使用@Query获取数据,但必须为每个条件复制大量 sql 行。 Example of one of the queries I have written in repository class is like below:我在存储库 class 中编写的其中一个查询示例如下所示:

    @Query(
        """ 
select  
                t.a as A,
                t.b as B,
                tt.c as C,
                p.d as D,
                p.e as E
            from Employee p
                join Department t on p.some_id = t.id
                join PersonalData tt on tt.id = t.some_id
                left outer join SalaryInformation ps on p.id = ps.come_id
                left outer join ManagerInformation sbt on p.some_id = sbt.id
                . few more joins here
                .
                .
                            
            where p.id= :id and p.interviewDate>=:dateFrom and p.interviewDate<=:dateTo
""" ,
        nativeQuery = true
    )
    fun findByEmployeeIdForInterviewDate(employeeId: Long, dateFrom:String, dateTo: String, pageable: Pageable): Slice<EmployeeDetailsProjection>

With current approach, I have to repeat this query for remaining date columns which I dont want to as it looks ugly.使用当前方法,我必须对剩余的日期列重复此查询,因为它看起来很难看。

Any better suggestions will be really helpful:)任何更好的建议都会很有帮助:)

I tried Specification Criteria API, but it was a dead end because I cannot use joins as there is no mapping between Entities like @OneToMany etc.我尝试了 Specification Criteria API,但这是一个死胡同,因为我无法使用连接,因为实体之间没有映射,如 @OneToMany 等。

Hibernate 6 introduces a JPA Criteria extension API which you can use to model joins to entities. Hibernate 6 引入了一个 JPA 条件扩展 API,您可以使用它来 model 加入实体。 To use Hibernate 6 you will have to update to Spring 3 though.要使用 Hibernate 6,您必须更新到 Spring 3。 For every JPA Criteria interface, Hibernate introduces a sub-interface prefixed with Jpa that contains the Hibernate JPA Criteria extensions.对于每个 JPA Criteria 接口,Hibernate 引入一个以Jpa为前缀的子接口,其中包含 Hibernate JPA Criteria 扩展。 You could do eg你可以这样做

JpaEntityJoin<SalaryInformation> ps = ((JpaRoot<?>) root).join(SalaryInformation.class, SqmJoinType.LEFT);
ps.on(cb.equal(root.get("id"), ps.get("comeId")));

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

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