如果将 Hibernate 与数据库(和 c3p0 dbpooling)一起使用仍然可以并且安全地绕过 Hibernate 直接获得连接
If using Hibernate with Database (and c3p0 dbpooling) is is still possible and safe to directly get connection bypassing Hibernate
将 Hibernate 4.3.11 与 H2 1.4.199 和 C3p0 结合使用
如果将 Hibernate 与数据库一起使用仍然可以并且安全地绕过 Hibernate 直接从池中获取连接?
我正在尝试编写一个 sql 查询,现在我知道我可以使用 session.createSQLQuery() 但是这个 returns 一个 Hibernate org.hibernate SQLQuery class而不是 java.sql.Connection,这对我尝试设置参数造成了问题,因此我想尝试使用 Connection。
试试这个。
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
sessionFactory.getSessionFactoryOptions().getServiceRegistry().getService(ConnectionProvider.class).getConnection();
我还没有测试过这个,现在不能做。我在 ConnectionProvider 上只有 50-50,因为我不确定 c3p0 的提供者 class 是什么。可能是 org.hibernate.c3p0.internal.C3P0ConnectionProvider
或者你已经知道了。
编辑 2019 年 11 月 10 日
据我所知,连接是从 org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
接口的实现返回的。
org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl
这两种实现都在从服务注册时内部维护的数据源或池化连接中获取 java.sql.Connection
。
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 );
}
如您所见,它们都有不同的连接处理方式。如果您关闭连接,我认为不会出现重大问题,因为第一个 returns 新连接和第二个在连接关闭时补充池。但是,如果您不打算关闭,请了解在您的应用程序中调用了哪个实现并确保您没有泄漏。
其他两个实现用于 Hikari 和 UserSupplied 模式。
将 Hibernate 4.3.11 与 H2 1.4.199 和 C3p0 结合使用
如果将 Hibernate 与数据库一起使用仍然可以并且安全地绕过 Hibernate 直接从池中获取连接?
我正在尝试编写一个 sql 查询,现在我知道我可以使用 session.createSQLQuery() 但是这个 returns 一个 Hibernate org.hibernate SQLQuery class而不是 java.sql.Connection,这对我尝试设置参数造成了问题,因此我想尝试使用 Connection。
试试这个。
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
sessionFactory.getSessionFactoryOptions().getServiceRegistry().getService(ConnectionProvider.class).getConnection();
我还没有测试过这个,现在不能做。我在 ConnectionProvider 上只有 50-50,因为我不确定 c3p0 的提供者 class 是什么。可能是 org.hibernate.c3p0.internal.C3P0ConnectionProvider
或者你已经知道了。
编辑 2019 年 11 月 10 日
据我所知,连接是从 org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
接口的实现返回的。
org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl
这两种实现都在从服务注册时内部维护的数据源或池化连接中获取 java.sql.Connection
。
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 );
}
如您所见,它们都有不同的连接处理方式。如果您关闭连接,我认为不会出现重大问题,因为第一个 returns 新连接和第二个在连接关闭时补充池。但是,如果您不打算关闭,请了解在您的应用程序中调用了哪个实现并确保您没有泄漏。
其他两个实现用于 Hikari 和 UserSupplied 模式。