如何从 Java 和 JPA 调用存储过程

2022-08-31 10:10:30

我正在编写一个简单的Web应用程序来调用存储过程并检索一些数据。它是一个非常简单的应用程序,可与客户的数据库进行交互。我们传递员工 ID 和公司 ID,存储过程将返回员工详细信息。

Web 应用程序无法更新/删除数据,并且正在使用 SQL Server。

我正在 Jboss AS 中部署我的 Web 应用程序。我应该使用 JPA 访问存储过程还是 .在这种情况下使用 JPA 的任何优点。CallableStatement

此外,调用此存储过程的 sql 语句是什么。我以前从未使用过存储过程,我正在为此而苦苦挣扎。谷歌并没有多大帮助。

下面是存储过程:

CREATE procedure getEmployeeDetails (@employeeId int, @companyId int)
as
begin
    select firstName, 
           lastName, 
           gender, 
           address
      from employee et
     where et.employeeId = @employeeId
       and et.companyId = @companyId
end

更新:

适用于在使用 JPA 调用存储过程时遇到问题的任何其他人。

Query query = em.createNativeQuery("{call getEmployeeDetails(?,?)}",
                                   EmployeeDetails.class)           
                                   .setParameter(1, employeeId)
                                   .setParameter(2, companyId);

List<EmployeeDetails> result = query.getResultList();

我注意到的事情:

  1. 参数名称对我不起作用,因此请尝试使用参数索引。
  2. 正确的 sql 语句,而不是{call sp_name(?,?)}call sp_name(?,?)
  3. 如果存储过程返回结果集,即使您知道只有一行,也不会起作用getSingleResult
  4. 传递名称或结果类详细信息resultSetMapping

答案 1

JPA 2.1 现在支持存储过程,请在此处阅读 Java 文档。

例:

StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("sales_tax");
// set parameters
storedProcedure.registerStoredProcedureParameter("subtotal", Double.class, ParameterMode.IN);
storedProcedure.registerStoredProcedureParameter("tax", Double.class, ParameterMode.OUT);
storedProcedure.setParameter("subtotal", 1f);
// execute SP
storedProcedure.execute();
// get result
Double tax = (Double)storedProcedure.getOutputParameterValue("tax");

请参阅此处的详细示例。


答案 2

我正在 Jboss AS 中部署我的 Web 应用程序。我应该使用 JPA 访问存储过程还是 CallableStatement。在这种情况下使用 JPA 的任何优点。

JPA并不真正支持它,但它是可行的。我仍然不会走这条路:

  • 使用JPA只是为了在某些bean中映射存储过程调用的结果,这真的是过分的,
  • 特别是考虑到JPA并不适合调用存储过程(语法将非常详细)。

因此,我宁愿考虑使用Spring支持JDBC数据访问,或者像MyBatis这样的数据映射器,或者考虑到应用程序的简单性,原始JDBC和。实际上,JDBC可能是我的选择。下面是一个基本的启动示例:CallableStatement

CallableStatement cstmt = con.prepareCall("{call getEmployeeDetails(?, ?)}");
cstmt.setInt("employeeId", 123);
cstmt.setInt("companyId", 456);
ResultSet rs = cstmt.executeQuery();

参考


推荐