如何使用返回参数从Hibernate调用Oracle函数?
我的问题非常类似于通过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 } });
是的,您确实需要使用out参数。 如果你使用doWork()方法,你会做这样的事情:
session.doWork(new Work() { public void execute(Connection conn) { CallableStatement stmt = conn.prepareCall("? = call (?)"); stmt.registerOutParameter(1, OracleTypes.INTEGER); stmt.setInt(2, ); stmt.execute(); Integer outputValue = stmt.getInt(1); // And then you'd do something with this outputValue } });
替代代码:)
如果你想直接结果,你可以使用下面的代码
int result = session.doReturningWork(new ReturningWork() { @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
我写了一篇关于从Hibernate调用Oracle存储过程和函数的各种方法的文章,所以总结一下,你有以下几种选择:
-
使用
@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
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(:id, :transId) FROM DUAL") .setParameter("postId", 1) .setParameter("transId", 1) .getSingleResult();
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 "); }
- 将jdbc驱动程序添加到类路径
- Hibernatevalidation – 仅validation对象是否为空
- 由于撇号,Hibernate中的QueryException
- 让JPA / Hibernate复制“ON DELETE SET NULL”function
- Hibernate持续vs保存
- Hibernate在单个表中对复合外键和主键进行一对一映射
- 正确使用Entity和DTO以在Restful Web服务中提供Json
- hibernate:从列表中删除项目不会保留
- java.lang.NoClassDefFoundError:org / hibernate / cache / EntityRegion配置EHCache