我正在尝试从使用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))
参数没问题,应用程序也没有显示错误。我看不出我错过了什么。
答案 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");
如果存储过程返回REFCURSOR
或TABLE
结果:
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();