1

Hibernate Session'doWork()方法可以直接访问java.sql.Connection.

以下是创建和执行PreparedStatement生成序列的方法之一

public Long generateId() {
    final Long id[] = { null };

    getSessionFactory().openSession().doWork(new Work() {
        public void execute(Connection connection) throws SQLException {
            PreparedStatement ps = connection
                    .prepareStatement("SELECT HIB_SEQ.nextval FROM DUAL");
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                id[0] = rs.getLong(0);
            }
        }
    });
    return id[0];
}

首先,有没有更好的方法来做到这一点?

第二个问题我们需要明确关闭PreparedStatement上面创建的吗?

4

3 回答 3

1

1)对于返回值,我们可以使用doReturningWork

public int updateEmployeeStatusWithCount(final List<String> employeeList) throws DBException
{
       Session session = null;
       try
       {
              session = HibernateUtil.getSession();
              session.beginTransaction();
              int cnt = session.doReturningWork(new ReturningWork<Integer>() {
                     @Override
                     public Integer execute(Connection conn) throws SQLException {
                           PreparedStatement pStmt = null;
                           try
                           {
                                  int updatedCnt = 0;
                                  String sqlQry = "UPDATE EMP_DETAILS set IS_ACTIVE='N' WHERE EMP_ID=?";
                                  pStmt = conn.prepareStatement(sqlQry);
                                  for(String empId:employeeList)
                                  {
                                         System.out.println(empId);
                                         pStmt.setString(1, empId);
                                         int cnt = pStmt.executeUpdate();
                                         updatedCnt+=cnt;
                                  }
                                  return updatedCnt;
                           }
                           finally
                           {
                                  pStmt.close();
                           }                                
                     }
              });
              session.getTransaction().commit();
              return cnt;
       }
       catch(HibernateException e)
       {
              throw new DBException("Error occured while updating Employee Status",e);
       }
       finally
       {
              HibernateUtil.closeSession(session);
       }            
}

2)是的,我们必须明确关闭PreparedStatement 见下面的例子

public void updateEmployeeStatus(final List<String> employeeList) throws DBException
{
       Session session = null;
       try
       {
              session = HibernateUtil.getSession();
              session.beginTransaction();
              session.doWork(new Work() {
                     @Override
                     public void execute(Connection conn) throws SQLException {
                           PreparedStatement pStmt = null;
                           try
                           {
                                  String sqlQry = "UPDATE EMP_DETAILS set IS_ACTIVE='N' WHERE EMP_ID=?";
                                  pStmt = conn.prepareStatement(sqlQry);
                                  for(String empId:employeeList)
                                  {
                                         pStmt.setString(1, empId);
                                         pStmt.addBatch();
                                  }
                                  pStmt.executeBatch();
                           }
                           finally
                           {
                                  pStmt.close();
                           }                                
                     }
              });
              session.getTransaction().commit();
       }
       catch(HibernateException e)
       {
              throw new DBException("Error occured while updating Employee Status",e);
       }
       finally
       {
              HibernateUtil.closeSession(session);
       }            
}

参考

于 2014-11-21T08:55:40.297 回答
1

的实例PreparedStatement是作为方法的一部分创建的Work.execute,因此应该在该范围内处理,包括关闭(一旦方法完成其执行,实例本身将由 GC 收集,因为变量ps将超出范围,但任何外部资源,例如打开游标需要显式调用ps.close())。

Connection另一方面,Hibernate 将一个实例传递给方法,不应手动关闭——这是 Hibernate 的责任。

于 2012-05-24T12:33:53.043 回答
0
    String query = ((SessionFactoryImplementor)sessionFactory).getDialect().getSequenceNextValString(seqName);
    Session session = sessionFactory.getCurrentSession();
    return (Long) session.createSQLQuery(query).addScalar("nextval", Hibernate.LONG).uniqueResult();

您可能需要稍微调整标量部分以适应数据库的列名和返回类型。

于 2012-05-24T11:16:56.413 回答