首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JPA存储存储过程返回值

问使用JPA存储存储过程返回值
EN

Stack Overflow用户
提问于 2018-05-09 05:47:59
回答 1查看 4.3K关注 0票数 1

我试图使用JPA (和Spring 2)来执行Server存储过程。以下是程序:

代码语言:javascript
复制
CREATE Procedure [dbo].[GetStatus] 
@statusId   char(32),
@bar    int
AS
BEGIN TRY
    SELECT IIF(COUNT(1)>0 , 1, 0)   FROM Status WITH (NOLOCK) 
    WHERE statusId = @statusId AND bar = @bar
END TRY
BEGIN CATCH
    EXEC EventLog @@PROCID
END CATCH
GO

我试图捕获返回值,但无法找到这样做的方法。我的实体是:

代码语言:javascript
复制
@Entity
@Table(name = "status")
@NamedStoredProcedureQueries({
        @NamedStoredProcedureQuery(name = "getStatusByStatusId",
                procedureName = "GetStatus",
                parameters = {
                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "statusId", type = String.class),
                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "bar", type = Integer.class)                    })
})
public class Status implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    private Integer bar;
    private String statusId;
    private Date createDate;
}

我的存储库是:

代码语言:javascript
复制
@Repository
public interface StatusRepository extends JpaRepository<Status, Long> {
    @Procedure("GetStatus")
    int getStatusByStatusId(@Param("statusId") String statusId, @Param("bar") Integer bar);
}

当我从服务层运行此方法时,会得到一个错误:

没有为存储过程定义参数输出.“

我尝试添加参数(通过将它命名为count并键入Integer)。我试过List,Object[],但是什么都没成功。唯一起作用的是,如果我将存储库方法更改为返回void。但在这种情况下,我无法得到返回值。那么,我的问题是,我如何才能得到这个选择值?任何帮助都是非常感谢的。我的app.yml有:

代码语言:javascript
复制
  datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://dev.lsd.com:1433;databaseName=Qrex;integratedSecurity=true;MultiSubnetFailover=true;authenticationScheme=JavaKerberos
    username:
    password:
  jpa:
    hibernate:
      ddl-auto: none
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    show-sql: true
    database-platform: org.hibernate.dialect.SQLServerDialect
    database: sql_server

我对等级的依赖是:

代码语言:javascript
复制
compile "com.microsoft.sqlserver:mssql-jdbc:6.4.0.jre8"
EN

回答 1

Stack Overflow用户

发布于 2018-05-09 08:56:07

我不相信JPA能够处理存储过程,返回任意数量的结果集和/或更新计数和/或错误消息。我看到的所有例子都很简单。您的过程可以返回:

  • 包含投影的结果集(不是实体!)
  • 无论EventLog过程返回什么。可能是任何东西

下面是如何直接使用JDBC (没有OUT参数,所以普通的PreparedStatement就可以这么做)。

下面是如何使用JDBC只获取一个结果集:

代码语言:javascript
复制
try (PreparedStatement stmt = connection.prepareStatement(
    "EXEC [GetStatus] ?, ?"
)) {
    stmt.setString(1, statusId);
    stmt.setInt(2, bar);

    if (stmt.execute()) {
        try (ResultSet rs = stmt.getResultSet()) {
            // Do your thing
        }
    }
}

下面是如何获取任意数量的结果集

如果您也想检索EventLog生成的任何内容,您可能更愿意调用它:

代码语言:javascript
复制
try (PreparedStatement stmt = connection.prepareStatement(
    "EXEC [GetStatus] ?, ?"
)) {
    stmt.setString(1, statusId);
    stmt.setInt(2, bar);

    fetchLoop:
    for (int i = 0, updateCount = 0; i < 256; i++) {
        boolean result = (i == 0)
            ? s.execute()
            : s.getMoreResults();

        if (result)
            try (ResultSet rs = s.getResultSet()) {
                System.out.println("Result      :");

                while (rs.next())
                    System.out.println("  " + rs.getString(1));
            }
        else if ((updateCount = s.getUpdateCount()) != -1)
            System.out.println("Update Count: " + updateCount);
        else
            break fetchLoop;
    }
}

我在这里更详细地描述了这种获取任意结果集和更新计数的方法。,特别是如何正确地获取异常和警告。

如果使用该方法,则可能需要将该逻辑封装在某些库代码中。

使用jOOQ

还有可能在这些方面使用jOOQ (免责声明:我为供应商工作),在这种情况下,您可以调用:

代码语言:javascript
复制
Results results = ctx.fetchMany("EXEC [GetStatus] ?, ?", statusId, bar);

若要获得org.jooq.Results类型,它包装交错的结果集、更新计数、异常和警告

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50246308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档