如何使用返回参数从Hibernate调用Oracle函数?

2022-09-02 11:16:30

我的问题非常像通过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。执行此类操作的推荐方法是什么?

有没有办法从我的语句中提取声明的变量?


答案 1

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

答案 2

您有以下选择:

  1. 使用 :@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();    
    
  2. 使用 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 ) );
         }
     } );            
    
  3. 使用本机 Oracle 查询:

     Integer result = (Integer) entityManager.createNativeQuery(
         "SELECT MYSCHEMA.MYFUNC(:postId, :transId) FROM DUAL")
         .setParameter("postId", 1)
         .setParameter("transId", 1)
         .getSingleResult();
    

推荐