【问题标题】:Custom Result handling by calling store procedure in Spring Data JPA通过在 Spring Data JPA 中调用存储过程来处理自定义结果
【发布时间】:2020-10-08 04:05:55
【问题描述】:

我需要调用带有输入参数的存储过程。此存储过程返回自定义结果集,我需要在返回 UI 之前进一步读取和处理该结果集。我们怎样才能做到这一点?

EG:

@Query("CALL SP_EMPLOYEE_REPORT(:year)",nativeQuery = true)
List<EmpolypeeCustomReportBean> getEmployeeReport(@param("year") Integer year);

【问题讨论】:

  • JPA 在使用存储过程时不是很方便。你可以看看jooq.org

标签: spring spring-boot hibernate spring-data-jpa spring-data


【解决方案1】:

给定以下存储过程。

CREATE PROCEDURE NAME_OF_THE_PROCEDURE(IN param VARCHAR(255), OUT retval INT)

您可以从接口查询中调用它:

@Procedure(value = "NAME_OF_THE_PROCEDURE")
int getFromStoredProcedure(String param);

同样由@Query注解:

@Query(value = "CALL NAME_OF_THE_PROCEDURE(:input_value);", nativeQuery = true)
Integer findSomeThing(@Param("input_value") Integer name);

或者你也可以使用命名存储过程查询。

@Entity
@NamedStoredProcedureQuery(name = "MyObj.getSomethingFromProc", 
  procedureName = "NAME_OF_THE_PROCEDURE", parameters = {
    @StoredProcedureParameter(mode = ParameterMode.IN, name = "param", type = String.class),
    @StoredProcedureParameter(mode = ParameterMode.OUT, name = "retval", type = Integer.class)})
public class MyObj{
    // class definition
}

然后调用它。

@Procedure(name = "MyObj.getSomethingFromProc")
Integer getSomethingFromStoredProc(@Param("param") String model);

您还可以在@NamedStoredProcedureQuery 中使用resultClassesresultSetMapping 属性来处理复杂的返回类型。

Complex example由Eclipselink提供:

   @NamedStoredProcedureQuery(
       name="ReadUsingMultipleResultSetMappings",
       procedureName="Read_Multiple_Result_Sets",
       resultSetMappings={"EmployeeResultSetMapping", "AddressResultSetMapping", "ProjectResultSetMapping", "EmployeeConstructorResultSetMapping"}
   )

   @SqlResultSetMappings({
       @SqlResultSetMapping(
           name = "EmployeeResultSetMapping",
           entities = {
               @EntityResult(entityClass = Employee.class)
           }
       ),
       @SqlResultSetMapping(
           name = "EmployeeConstructorResultSetMapping",
           classes = { 
               @ConstructorResult(
                   targetClass = EmployeeDetails.class,
                   columns = {
                       @ColumnResult(name="EMP_ID", type=Integer.class),
                       @ColumnResult(name="F_NAME", type=String.class),
                       @ColumnResult(name="L_NAME", type=String.class),
                       @ColumnResult(name="R_COUNT", type=Integer.class)
                   }
               )
           }
       )
   })
   public Employee(){
       ....
   }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 2018-10-06
    相关资源
    最近更新 更多