![](/img/trans.png)
[英]how to call a sql server function from hibernate with return parameter?
[英]How to call an Oracle function from Hibernate with a return parameter?
我的問題很像通過 Hibernate 獲取 PL/SQL 函數的返回值
我有一個函數在內部進行一些修改並返回一個值。
最初的想法是做這樣的事情:
protected Integer checkXXX(Long id, Long transId)
throws Exception {
final String sql = "SELECT MYSCHEMA.MYFUNC(" + id + ", "
+ transId + ") FROM DUAL";
final BigDecimal nr = (BigDecimal) this.getHibernateTemplate()
.getSessionFactory().getCurrentSession().createSQLQuery(sql)
.uniqueResult();
return nr.intValue();
}
不幸的是,這不適用於 Oracle。 做這樣的事情的推薦方法是什么?
有沒有辦法從我的語句中提取聲明的變量?
Hibernate Session 提供了一個doWork()
方法,讓您可以直接訪問java.sql.Connection
。 然后您可以創建並使用java.sql.CallableStatement
來執行您的函數:
session.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
CallableStatement call = connection.prepareCall("{ ? = call MYSCHEMA.MYFUNC(?,?) }");
call.registerOutParameter( 1, Types.INTEGER ); // or whatever it is
call.setLong(2, id);
call.setLong(3, transId);
call.execute();
int result = call.getInt(1); // propagate this back to enclosing class
}
});
您有以下選擇:
使用@NamedNativeQuery
:
@org.hibernate.annotations.NamedNativeQuery( name = "fn_my_func", query = "{ ? = call MYSCHEMA.MYFUNC(?, ?) }", callable = true, resultClass = Integer.class ) Integer result = (Integer) entityManager.createNamedQuery("fn_my_func") .setParameter(1, 1) .setParameter(2, 1) .getSingleResult();
使用 JDBC API:
Session session = entityManager.unwrap( Session.class ); final AtomicReference<Integer> result = new AtomicReference<>(); session.doWork( connection -> { try (CallableStatement function = connection .prepareCall( "{ ? = call MYSCHEMA.MYFUNC(?, ?) }" ) ) { function.registerOutParameter( 1, Types.INTEGER ); function.setInt( 2, 1 ); function.setInt( 3, 1 ); function.execute(); result.set( function.getInt( 1 ) ); } } );
使用本機 Oracle 查詢:
Integer result = (Integer) entityManager.createNativeQuery( "SELECT MYSCHEMA.MYFUNC(:postId, :transId) FROM DUAL") .setParameter("postId", 1) .setParameter("transId", 1) .getSingleResult();
是的,您確實需要使用 out 參數。 如果你使用 doWork() 方法,你會做這樣的事情:
session.doWork(new Work() {
public void execute(Connection conn) {
CallableStatement stmt = conn.prepareCall("? = call <some function name>(?)");
stmt.registerOutParameter(1, OracleTypes.INTEGER);
stmt.setInt(2, <some value>);
stmt.execute();
Integer outputValue = stmt.getInt(1);
// And then you'd do something with this outputValue
}
});
替代代碼:)
如果你想直接結果,你可以使用下面的代碼
int result = session.doReturningWork(new ReturningWork<Integer>() {
@Override
public Integer execute(Connection connection) throws SQLException {
CallableStatement call = connection.prepareCall("{ ? = call MYSCHEMA.MYFUNC(?,?) }");
call.registerOutParameter( 1, Types.INTEGER ); // or whatever it is
call.setLong(2, id);
call.setLong(3, transId);
call.execute();
return call.getInt(1); // propagate this back to enclosing class
}
});
http://keyurj.blogspot.com.tr/2012/12/dowork-in-hibernate.html
public static void getThroHibConnTest() throws Exception {
logger.debug("UsersActiion.getThroHibConnTest() | BEG ");
Transaction tx = null;
Connection conn = null;
CallableStatement cs = null;
Session session = HibernateUtil.getInstance().getCurrentSession();
try {
tx = session.beginTransaction();
conn = session.connection();
System.out.println("Connection = "+conn);
if (cs == null)
{
cs =
conn.prepareCall("{ ?=call P_TEST.FN_GETSUM(?,?) }");
}
cs.clearParameters();
cs.registerOutParameter(1,OracleTypes.INTEGER);
cs.setInt(2,1);
cs.setInt(3,2);
cs.execute();
int retInt=cs.getInt(1);
tx.commit();
}catch (Exception ex) {
logger.error("UsersActiion.getThroHibConnTest() | ERROR | " , ex);
if (tx != null && tx.isActive()) {
try {
// Second try catch as the rollback could fail as well
tx.rollback();
} catch (HibernateException e1) {
logger.debug("Error rolling back transaction");
}
// throw again the first exception
throw ex;
}
}finally{
try {
if (cs != null) {
cs.close();
cs = null;
}
if(conn!=null)conn.close();
} catch (Exception ex){;}
}
logger.debug("UsersActiion.getThroHibConnTest() | END ");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.