如何实现它的简单示例:
- 数据库架构。
create table MY_PATIENT
(
PAT_RECID number,
PAT_NAME varchar2(100),
constraint PAT_PK primary key(PAT_RECID)
);
create table MY_ORDER
(
ORD_RECID number,
ORD_CODE varchar2(15),
ORD_PATID number,
constraint ORD_PK primary key(ORD_RECID),
constraint ORD_PAT_FK foreign key(ORD_PATID) references MY_PATIENT(PAT_RECID),
constraint ORD_CODE_UNIQUE unique (ORD_CODE)
);
CREATE OR REPLACE PROCEDURE fetch_patient_orders(
patientId IN NUMBER,
patientOrders OUT SYS_REFCURSOR)
AS
BEGIN
OPEN patientOrders FOR
SELECT *
FROM MY_ORDER
WHERE ORD_PATID = patientId;
END;
- 实体定义。
@NamedStoredProcedureQueries(
@NamedStoredProcedureQuery(
name = "fetch_patient_orders",
procedureName = "fetch_patient_orders",
resultClasses = Order.class,
parameters = {
@StoredProcedureParameter(
name = "patientId",
type = Long.class,
mode = ParameterMode.IN
),
@StoredProcedureParameter(
name = "patientOrders",
type = Class.class,
mode = ParameterMode.REF_CURSOR
)
}
)
)
@Entity
@Table(name = "MY_ORDER")
public class Order
{
@Id
@Column(name = "ORD_RECID")
private Long id;
@Column(name = "ORD_CODE")
private String code;
@ManyToOne
@JoinColumn(name = "ORD_PATID")
private Patient patient;
}
- 及用法:
List<Order> orders = session.createNamedStoredProcedureQuery("fetch_patient_orders")
.setParameter("patientId", 2L)
.getResultList();
已使用 hibernate 5.4.12.Final、ojdbc8.jar、Oracle12cDialect 进行了测试。
另见休眠documentation。
上述方法适用于纯休眠应用程序,但不适用于 Spring Boot 应用程序。
根据弹簧靴documentation:
连接到生产数据库
生产数据库连接也可以通过使用池DataSource 自动配置。 Spring Boot 使用以下算法来选择特定的实现:
-
我们更喜欢 HikariCP 的性能和并发性。如果 HikariCP 可用,我们总是选择它。
-
否则,如果 Tomcat 池化 DataSource 可用,我们就使用它。
-
如果 HikariCP 和 Tomcat 池数据源都不可用,并且如果 Commons DBCP2 可用,我们使用它。
如果您使用 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa “starters”,您将自动获得对 HikariCP 的依赖。
您可以完全绕过该算法并通过设置spring.datasource.type 属性来指定要使用的连接池。
所以,spring boot 默认使用 HikariCP JDBC 连接池。而且貌似REF_CURSOR参数注册有问题:
o.h.r.j.i.ResourceRegistryStandardImpl : Registering statement [HikariProxyCallableStatement@770201936 wrapping oracle.jdbc.driver.OracleCallableStatementWrapper@528a6369]
o.h.type.descriptor.sql.BasicBinder : binding parameter [patientId] as [BIGINT] - [2]
o.h.s.i.AbstractServiceRegistryImpl : Initializing service [role=org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport]
o.h.engine.jdbc.spi.SqlExceptionHelper : Error registering REF_CURSOR parameter [patientOrders] [n/a]
当我使用application.properties中的oracle特定数据源池时:
# com.zaxxer.hikari.HikariDataSource (default value)
spring.datasource.type=oracle.jdbc.pool.OracleDataSource
一切正常。