kan*_*arp 17 java database orm stored-procedures hibernate
我们如何使用Hibernate或JPA调用存储过程?
Vla*_*cea 17
考虑以下只返回基本返回值的存储过程:
CREATE OR REPLACE PROCEDURE count_comments (
postId IN NUMBER,
commentCount OUT NUMBER )
AS
BEGIN
SELECT COUNT(*) INTO commentCount
FROM post_comment
WHERE post_id = postId;
END;
Run Code Online (Sandbox Code Playgroud)
您可以使用标准JPA调用此方法:
StoredProcedureQuery query = entityManager
.createStoredProcedureQuery("count_comments")
.registerStoredProcedureParameter(1, Long.class,
ParameterMode.IN)
.registerStoredProcedureParameter(2, Long.class,
ParameterMode.OUT)
.setParameter(1, 1L);
query.execute();
Long commentCount = (Long) query.getOutputParameterValue(2);
Run Code Online (Sandbox Code Playgroud)
如果存储过程返回SYS_REFCURSOR:
CREATE OR REPLACE PROCEDURE post_comments (
postId IN NUMBER,
postComments OUT SYS_REFCURSOR )
AS
BEGIN
OPEN postComments FOR
SELECT *
FROM post_comment
WHERE post_id = postId;
END;
Run Code Online (Sandbox Code Playgroud)
你可以这样称呼它:
StoredProcedureQuery query = entityManager
.createStoredProcedureQuery("post_comments")
.registerStoredProcedureParameter(1, Long.class,
ParameterMode.IN)
.registerStoredProcedureParameter(2, Class.class,
ParameterMode.REF_CURSOR)
.setParameter(1, 1L);
query.execute();
List<Object[]> postComments = query.getResultList();
Run Code Online (Sandbox Code Playgroud)
如果要调用Oracle数据库函数:
CREATE OR REPLACE FUNCTION fn_count_comments (
postId IN NUMBER )
RETURN NUMBER
IS
commentCount NUMBER;
BEGIN
SELECT COUNT(*) INTO commentCount
FROM post_comment
WHERE post_id = postId;
RETURN( commentCount );
END;
Run Code Online (Sandbox Code Playgroud)
你不能使用StoredProcedureQuery它,因为它不适用于Hibernate 5,所以你可以像这样调用它:
BigDecimal commentCount = (BigDecimal) entityManager
.createNativeQuery(
"SELECT fn_count_comments(:postId) FROM DUAL"
)
.setParameter("postId", 1L)
.getSingleResult();
Run Code Online (Sandbox Code Playgroud)
或使用纯JDBC:
Session session = entityManager.unwrap( Session.class );
Integer commentCount = session.doReturningWork( connection -> {
try (CallableStatement function = connection.prepareCall(
"{ ? = call fn_count_comments(?) }" )) {
function.registerOutParameter( 1, Types.INTEGER );
function.setInt( 2, 1 );
function.execute();
return function.getInt( 1 );
}
} );
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请查看以下文章:
您可以执行以下操作
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
PreparedStatement st = session.connection().prepareStatement("{call procedureName(?, ?)}");
st.setString(1, formatter.format(parameter1));
st.setString(2, formatter.format(parameter2));
st.execute();
tx.commit();
Run Code Online (Sandbox Code Playgroud)
请在需要的地方添加异常处理。