【问题标题】:Is it necessary to close the connection explicitly when getting connection from Hibernate sessionFactory.getCurrentSession() for prepareStatement从 Hibernate sessionFactory.getCurrentSession() 获取连接以进行 prepareStatement 时是否需要显式关闭连接
【发布时间】:2020-09-22 07:24:33
【问题描述】:

我想在 Spring Boot 应用程序中使用preparedstatement 插入一些记录。所以我已经使用休眠建立了数据库连接(HibernateConfig - 仅用于数据库连接)。因为我要使用preparedstatement,所以我从Hibernate SessionFactorySession 获得了Connection

我知道,当使用 getCurrentSession 时,事务管理本身会处理休眠操作,如 session.beginTransaction() 和 session.save()。

在使用sessionFactory.getCurrentSession() 时,我是否需要在 finally 块中明确关闭连接和其他内容?请检查以下代码中的 finally 块:

在 DAOImpl 文件中

@Repository
@Transactional
public class TestDAOImpl implements TestDAO {

@Autowired
private SessionFactory sessionFactory;

public Connection getConnection(){
         Session session = sessionFactory.getCurrentSession();
         Connection conn = session.doReturningWork(new ReturningWork<Connection>() {
                @Override
                public Connection execute(Connection conn) throws SQLException {
                    return conn;
                }
         });
        return conn;
}

public void insertRecords() {
     Connection conn= getConnection();
     PreparedStatement ps = null;
     try {
         String inserQuery ="INSERT IN TO TEST VALUES(?,?,?)" //some insert statement
         conn.setAutoCommit(false);
         ps = conn.prepareStatement(inserQuery);
         //set values ps.setString() and ps.addBatch(); -some code here

         int[] insertCounts = ps.executeBatch();
         conn.commit();
     } catch(BatchUpdateException e){

     } catch(SQLException e){

     } finally {
           if(ps!=null)ps.close();
           if(conn!=null) conn.close();
           if(sessionFactory!=null) sessionFactory.close();
 }
}

请注意,我在同一个 DAOImpl 类中使用了另外 3 个方法,并为每个方法创建连接 Connection conn= getConnection(); 并在 finally 块中关闭。

还请告诉我从 SessionFactory 获取连接的最佳做法或任何其他替代方式。

【问题讨论】:

  • 你为什么要使用会话工厂,为什么不注入javax.sql.DataSource 并从那里获取连接?我强烈推荐学习 try-with-resources:它会简化你的代码。
  • 当我们使用@Autowired private DataSource dataSource 时,我有几个问题;用于数据库连接。纠正我的假设,1。在这种情况下,我应该手动关闭所有连接。 2.我怎样才能读取我所有的休眠属性,比如方言。 3. 事务管理在这里是不可能的吧。 4. 最多可以连接多少个。 5.我怎样才能确保所有的连接都关闭了,有什么办法可以找到它。 6. 是spring boot应用的最佳方式吗

标签: java spring hibernate jdbc sessionfactory


【解决方案1】:

是的,您绝对应该关闭连接以防止内存泄漏。 此外,最好的方法是使用 try-with-resources 语句,它会自动关闭您在其中打开的可关闭资源。

try(Connection con = getConnection; Statement stmt = con.prepareStatement(insertSql)) {
...
} catch(Exception e) {
...}

这种方式也不需要 finally 块。

编辑:仅供参考,如果您不关闭连接,它将保持打开状态,直到您关闭应用程序,并且每个后续调用都会打开一个新的。我想你可以想象这意味着什么,当你的数据库一次只允许最多 100 个打开的连接时。

【讨论】:

  • 我同意,但是当我使用 getCurrentSession() 时,休眠会自动控制事务关闭..无需明确提及。这就是我在这里澄清的原因。
  • 事务不等同于连接。
【解决方案2】:

按照@MarkRotteveel 的建议,我删除了休眠配置文件并添加了以下代码

@Configuration
public class DataSourceConfig {

    @Bean("dataSource")
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

}

在 DAOImpl 类中,

@Autowired
private DataSource dataSource;

try(Connection conn= dataSource.getConnection();
       PreparedStatement ps = conn.prepareStatement(inserQuery);) {
    .....
}catch(Exception e){
    ....
}

如果这里需要任何修改,请检查并告诉我。

【讨论】:

  • 如何在这里使用连接池以获得更好的性能?请提供任何样品
猜你喜欢
  • 2013-03-04
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多