java - 如果将 Hibernate 与数据库(和 c3p0 dbpooling)一起使用仍然可以安全地绕过 Hibernate 直接获得连接
问题描述
将 Hibernate 4.3.11 与 H2 1.4.199 和 C3p0 一起使用
如果将 Hibernate 与数据库一起使用仍然可以并且安全地绕过 Hibernate 从池中直接获取连接?
我正在尝试编写一个 sql 查询,现在我知道我可以使用 session.createSQLQuery() 但这会返回一个 Hibernate org.hibernate SQLQuery 类而不是 java.sql.Connection,这对我尝试设置参数造成了问题,所以我想尝试使用 Connection 代替。
解决方案
尝试这个。
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
sessionFactory.getSessionFactoryOptions().getServiceRegistry().getService(ConnectionProvider.class).getConnection();
我没有对此进行测试,目前无法执行此操作。我在 ConnectionProvider 上只有 50-50 岁,因为我不确定 c3p0 的提供程序类是什么。可能是org.hibernate.c3p0.internal.C3P0ConnectionProvider
,或者你已经知道了。
编辑 11-10-2019
org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
据我所知,连接是从接口的实现返回的。
org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl
这两种实现都java.sql.Connection
从服务注册时内部维护的 Datasource 或 PooledConnections 获取。
DatasourceConnectionProviderImpl
有以下方法。
@Override
public Connection getConnection() throws SQLException {
if ( !available ) {
throw new HibernateException( "Provider is closed!" );
}
return useCredentials ? dataSource.getConnection( user, pass ) : dataSource.getConnection();
}
@Override
public void closeConnection(Connection connection) throws SQLException {
connection.close();
}
DriverManagerConnectionProviderImpl
方法如下
@Override
public Connection getConnection() throws SQLException {
if ( !active ) {
throw new HibernateException( "Connection pool is no longer active" );
}
return pool.poll();
}
public Connection poll() throws SQLException {
Connection conn = availableConnections.poll();
if ( conn == null ) {
synchronized (allConnections) {
if(allConnections.size() < maxSize) {
addConnections( 1 );
return poll();
}
}
throw new HibernateException( "The internal connection pool has reached its maximum size and no connection is currently available!" );
}
conn.setAutoCommit( autoCommit );
return conn;
}
@Override
public void closeConnection(Connection conn) throws SQLException {
if (conn == null) {
return;
}
pool.add( conn );
}
正如你所看到的,它们都有不同的处理连接的方式。如果您关闭连接,我不会想象会出现重大问题,因为第一个连接会返回新连接,而第二个连接会在连接关闭时补充池。但是,如果您不打算关闭,请知道在您的应用程序中调用了哪个实现,并确保您没有泄漏。
其他两个实现用于 Hikari 和 UserSupplied 模式。
推荐阅读
- qt - QT 覆盖 .txt 文件
- docker - 基于参数运行 docker build
- r - 计算区域中的对象数
- javascript - 我有一个包含所有项目的 JSON,我想要一种将项目自动添加到嵌入页面的方法,但它会为每个项目发送新的嵌入
- reactjs - 错误:尝试预期。ts(1005)。在反应中使用firebase实现登录/注册时
- python - NUMPY (python) 和 ARMADILLO (c++) 给出不同的结果
- java - 使用 javax.persistence.EntityManager 将实体添加到我的 SQL 数据库时出错
- php - POST 类型的路由在 Laravel 的服务器上不起作用
- pandas - Pandas:如何获取非唯一索引的索引值
- aws-api-gateway - AWS API网关,同名不同参数的get和post