如何从Hibernate调用MySQL存储过程

时间:2013-01-16 04:51:44

标签: java mysql database hibernate stored-procedures

我正在尝试从使用MySQL的Java Application调用MySQL存储过程。下面是DAO中用于调用存储过程“insertComm”

的部分
String opt="REFUND";
        Query query = this.getSession().createSQLQuery("CALL insertComm (:remitNo,     :opt)")
           .setParameter("remitNo", remitNo)
               .setParameter("opt", opt);
opt=query.toString();
hemappLogger.info(opt);

但是当我查询数据库并检查时,存储过程尚未执行。 'opt'值显示为     SQLQueryImpl(CALL insertComm(:remitNo,:opt))

参数没问题,应用程序也没有显示错误。我看不出我错过了什么。

3 个答案:

答案 0 :(得分:2)

我写了一篇关于how you can call MySQL stored procedures and database functions from Hibernate的非常详细的文章,但我也会在这里写一篇简短的摘要。

考虑到您有一个输出基本类型的简单存储过程:

CREATE PROCEDURE count_comments (
   IN postId INT, 
   OUT commentCount INT
) 
BEGIN
    SELECT COUNT(*) INTO commentCount 
    FROM post_comment  
    WHERE post_comment.post_id = postId; 
END

您可以使用JPA StoredProcedureQuery

调用此存储过程
StoredProcedureQuery query = entityManager
    .createStoredProcedureQuery("count_comments")
    .registerStoredProcedureParameter(
        "postId", Long.class, ParameterMode.IN)
    .registerStoredProcedureParameter(
        "commentCount", Long.class, ParameterMode.OUT)
    .setParameter("postId", 1L);

query.execute();

Long commentCount = (Long) query
    .getOutputParameterValue("commentCount");

如果存储过程返回REFCURSORTABLE结果:

CREATE PROCEDURE post_comments(IN postId INT) 
BEGIN
    SELECT *  
    FROM post_comment   
    WHERE post_id = postId;  
END

您需要按如下方式调用存储过程:

StoredProcedureQuery query = entityManager
    .createStoredProcedureQuery("post_comments");
query.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN);

query.setParameter(1, 1L);

List<Object[]> postComments = query.getResultList();

对于数据库函数,它返回结果集而不是将其放在OUT变量中:

CREATE FUNCTION fn_count_comments(postId integer)
RETURNS integer
DETERMINISTIC 
READS SQL DATA 
BEGIN
    DECLARE commentCount integer; 
    SELECT COUNT(*) INTO commentCount 
    FROM post_comment  
    WHERE post_comment.post_id = postId; 
    RETURN commentCount; 
END

Hibernate 4.x和5.x API对你没有帮助,你必须改用JDBC:

int 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);
    }
});

答案 1 :(得分:1)

您没有向实体会话对象添加实体... .addEntity(classname.class).setParameter()

答案 2 :(得分:1)

很遗憾,您无法使用Session.createSQLQuery()调用存储过程。顾名思义,它允许创建SQL 查询。过程调用不是查询。

但不要担心,解决的问题就是这个。

Connection conn = getSession().connection();
CallableStatment stat = conn.prepareCall("{CALL insertComm (?,?)}");
stat.setString(1, remitNo); // Assuming both parameters are String
stat.setString(2, opt);

stat.executeUpdate();
stat.close();