此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data JPA 3.4.0! |
存储过程
JPA 2.1 规范引入了对使用 JPA 条件查询 API 调用存储过程的支持。
我们引入了@Procedure
用于在存储库方法上声明存储过程元数据的注释。
下面的示例使用以下存储过程:
plus1inout
HSQL DB 中的过程。/;
DROP procedure IF EXISTS plus1inout
/;
CREATE procedure plus1inout (IN arg int, OUT res int)
BEGIN ATOMIC
set res = arg + 1;
END
/;
存储过程的元数据可以使用NamedStoredProcedureQuery
实体类型上的注释。
@Entity
@NamedStoredProcedureQuery(name = "User.plus1", procedureName = "plus1inout", parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) })
public class User {}
请注意,@NamedStoredProcedureQuery
具有两个不同的存储过程名称。name
是 JPA 使用的名称。procedureName
是存储过程在数据库中的名称。
您可以通过多种方式从存储库方法引用存储过程。
要调用的存储过程可以使用value
或procedureName
属性的@Procedure
注解。
这直接引用数据库中的存储过程,并忽略任何通过@NamedStoredProcedureQuery
.
或者,您可以指定@NamedStoredProcedureQuery.name
属性作为@Procedure.name
属性。
如果两者都不是value
,procedureName
也不name
配置后,存储库方法的名称将用作name
属性。
下面的示例演示如何引用显式映射的过程:
@Procedure("plus1inout")
Integer explicitlyNamedPlus1inout(Integer arg);
以下示例等效于上一个示例,但使用procedureName
别名:
procedureName
别名。@Procedure(procedureName = "plus1inout")
Integer callPlus1InOut(Integer arg);
以下内容再次等效于前两个,但使用方法名称而不是显式 annotation 属性。
EntityManager
通过使用 Method Name 来执行。@Procedure
Integer plus1inout(@Param("arg") Integer arg);
以下示例演示如何通过引用@NamedStoredProcedureQuery.name
属性。
EntityManager
.@Procedure(name = "User.plus1IO")
Integer entityAnnotatedCustomNamedProcedurePlus1IO(@Param("arg") Integer arg);
如果被调用的存储过程具有单个 out 参数,则该参数可以作为方法的返回值返回。
如果在@NamedStoredProcedureQuery
注解,这些可以作为Map
其中 key 是@NamedStoredProcedureQuery
注解。
请注意,如果存储过程返回ResultSet 然后任意OUT parameters 的 JSON 表达式,因为 Java 只能返回一个方法返回值,除非该方法声明了Map return 类型。 |
以下示例说明如何获取多个OUT
parameters (如果存储过程有多个OUT
参数,并注册为@NamedStoredProcedureQuery
.@NamedStoredProcedureQuery
需要注册才能提供参数元数据。
@Entity
@NamedStoredProcedureQuery(name = "User.multiple_out_parameters", procedureName = "multiple_out_parameters", parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, name = "some_cursor", type = void.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) })
public class User {}
@Procedure(name = "User.multiple_out_parameters")
Map<String, Object> returnsMultipleOutParameters(@Param("arg") Integer arg);