You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:59:20