Spring Boot 1.4.7环境下如何从Hibernate现有连接池获取连接?
从Hibernate现有连接池获取JDBC连接执行原生SQL
当然可以!完全不用额外创建第二个连接池,你可以直接通过Hibernate的EntityManager或者Session拿到现有连接池里的JDBC连接,既节省资源又能满足多次执行的需求。下面给你两种靠谱的实现方式:
方法一:用EntityManager + Session的doWork(推荐,自动管理连接)
这是Hibernate官方推荐的方式,它会自动帮你从连接池获取连接,执行完后自动归还,完全不用担心连接泄漏的问题,特别适合多次执行的场景。
import org.hibernate.Session; import org.hibernate.jdbc.Work; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @Service public class NativeQueryService { @PersistenceContext private EntityManager entityManager; public void runNativeQuery() { // 从EntityManager中解包得到Hibernate Session Session hibernateSession = entityManager.unwrap(Session.class); // 使用doWork方法执行原生SQL操作 hibernateSession.doWork(new Work() { @Override public void execute(Connection connection) throws SQLException { // 这里的connection就是来自Hibernate连接池的实例 String nativeSql = "SELECT name, create_time FROM user WHERE id = ?"; try (PreparedStatement stmt = connection.prepareStatement(nativeSql)) { stmt.setInt(1, 1001); ResultSet rs = stmt.executeQuery(); // 处理查询结果 while (rs.next()) { String userName = rs.getString("name"); // ... 你的业务逻辑处理 } } } }); } }
这种方式的好处是:连接的获取和释放全由Hibernate托管,你只需要专注于SQL逻辑即可,完全避免了手动管理连接的风险。
方法二:直接从Session获取连接(不推荐,需手动管理)
如果你确实需要直接持有Connection对象,也可以通过Session拿到,但必须手动关闭连接归还到池里,否则会导致连接池耗尽,影响系统性能:
public void getConnectionManually() throws SQLException { Session hibernateSession = entityManager.unwrap(Session.class); Connection connection = hibernateSession.connection(); try { String insertSql = "INSERT INTO operation_log(content) VALUES (?)"; try (PreparedStatement stmt = connection.prepareStatement(insertSql)) { stmt.setString(1, "执行了原生SQL操作"); stmt.executeUpdate(); } } finally { // 务必手动关闭连接,归还到连接池 if (connection != null && !connection.isClosed()) { connection.close(); } } }
额外注意事项
- 如果你当前处于事务中,获取的连接会自动参与到当前事务里,事务的提交/回滚会同步影响原生SQL的执行结果
- 确保你的Spring Boot配置已经正确初始化了Hibernate的连接池(Spring Boot 1.4.7默认使用Tomcat JDBC连接池,你也可以配置HikariCP等其他池,不影响上述方法的使用)
- 避免长时间占用连接,尽量在短时间内完成SQL操作,防止连接池资源被占满
内容的提问来源于stack exchange,提问作者Andreas Gottardi
相关产品推荐
相关产品推荐

