文章摘要(AI生成)
本文介绍了数据库连接池的创建过程和配置属性讲解。文章主要以GenericObjectPool.create()方法为切入点,详细讲解了数据库连接池的初始化过程。在连接池的创建过程中,使用了PoolableConnectionFactory.makeObject方法来创建具体的数据库连接。这里提到了池化连接PoolableConnection继承了DelegatingConnection,实现了Connection接口,Connection接口可以执行SQL语句并返回结果。文章还介绍了Connection接口的一些主要方法,包括createStatement方法用于创建Statement对象发送SQL语句到数据库。总体来说,本文详细介绍了数据库连接池的创建和配置过程。
数据库连接的具体创建
连接创建过程
在我们前几篇文章中,已经知道在创建数据库连接池时,会由PoolableConnectionFactory
来创建相应的数据库连接池,并且在上一篇文章中我们已经详细讲述了对象连接池的通用属性,这篇文章我们就由对象池GenericObjectPool.create()
方法为切入点,来看具体初始化数据库连接池的过程,以及数据库连接池的配置属性讲解。对应流程为下:
GenericObjectPool.create()
方法会调用连接池的PoolableConnectionFactory.makeObject
方法创建具体的数据库连接。PoolableConnectionFactory.makeObject
具体创建连接的过程如下:
其中池化连接PoolableConnection
继承了DelegatingConnection
,实现了Connection
。且还
Connection
接口
Connection
接口是与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。
连接对象的数据库能够提供描述其表、支持的 SQL 语法、存储过程、此连接的功能等的信息。此信息是使用 getMetaData 方法获得的。
注意:配置 Connection 时,JDBC 应用程序应使用适当的 Connection 方法,例如 setAutoCommit 或 setTransactionIsolation。当有可用的 JDBC 方法时,应用程序不应直接调用 SQL 命令来更改连接的配置。默认情况下,Connection 对象处于自动提交模式,这意味着它会在执行每个语句后自动提交更改。如果禁用了自动提交模式,则必须显式调用提交方法才能提交更改;否则,数据库更改将不会被保存。
我们看下Connection
接口定义了哪些主要方法:
方法 | 作用 |
---|---|
createStatement |
创建一个 Statement 对象,用于将 SQL 语句发送到数据库。 不带参数的 SQL 语句通常使用 Statement 对象执行。 如果多次执行相同的 SQL 语句,使用PreparedStatement 对象可能更有效。使用返回的 Statement 对象创建的结果集默认类型为 TYPE_FORWARD_ONLY ,并发级别为 CONCUR_READ_ONLY 。 可以通过调用 getHoldability 来确定创建的结果集的可持有性。 |
prepareStatement |
创建一个 PreparedStatement 对象,用于将参数化 SQL 语句发送到数据库。带或不带 IN 参数的 SQL 语句都可以预编译并存储在 PreparedStatement 对象中。 然后可以使用该对象多次有效地执行该语句。注意:此方法针对处理受益于预编译的参数化 SQL 语句进行了优化。 如果驱动支持预编译,方法 prepareStatement 会将语句发送到数据库进行预编译。 某些驱动程序可能不支持预编译。 在这种情况下,在执行PreparedStatement 对象之前,可能不会将语句发送到数据库。 这对用户没有直接影响; 但是,它确实会影响哪些方法抛出某些 SQLException 对象。 |
prepareCall |
创建用于调用数据库存储过程的 CallableStatement 对象。 CallableStatement 对象提供了用于设置其 IN 和 OUT 参数的方法,以及用于执行对存储过程的调用的方法。 |
nativeSQL |
将给定的 SQL 语句转换为系统的本机 SQL 语法。 驱动程序可以在发送 JDBC SQL 语法之前将其转换为系统的本机 SQL 语法。 此方法返回驱动程序将发送的语句的本机形式。 |
setAutoCommit |
将此连接的自动提交模式设置为给定状态。 如果连接处于自动提交模式,则其所有 SQL 语句将作为单独的事务执行和提交。 否则,它的 SQL 语句被分组到事务中,这些事务通过调用方法提交或方法回滚来终止。 默认情况下,新连接处于自动提交模式。 提交发生在语句完成时。 语句完成的时间取决于 SQL 语句的类型: 1. 对于 DML 语句,如 Insert 、Update 或 Delete ,以及 DDL 语句,一旦执行完毕,语句就完成了。2. 对于 Select 语句,当关联的结果集关闭时语句完成。3. 对于 CallableStatement 对象或返回多个结果的语句,当所有关联的结果集都已关闭并且所有更新计数和输出参数都已检索时,语句才完成。 |
commit |
将此连接的自动提交模式设置为给定状态。 如果连接处于自动提交模式,则其所有 SQL 语句将作为单独的事务执行和提交。 否则,它的 SQL 语句被分组到事务中,这些事务通过调用方法提交或方法回滚来终止。 默认情况下,新连接处于自动提交模式。 提交发生在语句完成时。 语句完成的时间取决于 SQL 语句的类型: 对于 DML 语句,如 Insert、Update 或 Delete,以及 DDL 语句,一旦执行完毕,语句就完成了。 对于 Select 语句,当关联的结果集关闭时语句完成。 对于 CallableStatement 对象或返回多个结果的语句,当所有关联的结果集都已关闭并且所有更新计数和输出参数都已检索时,语句才完成。 |
rollback |
撤消在当前事务中所做的所有更改并释放当前由此 Connection 对象持有的所有数据库锁。 只有在禁用自动提交模式时才应使用此方法。 |
close |
立即释放此 Connection 对象的数据库和 JDBC 资源,而不是等待它们自动释放。 |
isClosed |
检索此 Connection 对象是否已关闭。 如果已调用方法 close 或发生某些致命错误,则连接将关闭。 只有在调用 Connection.close 方法之后调用此方法,才能保证返回 true。通常不能调用此方法来确定与数据库的连接是有效还是无效。 典型的客户端可以通过捕获尝试操作时可能抛出的任何异常来确定连接无效。 |
setReadOnly |
将此连接置于只读模式,以提示驱动程序启用数据库优化。 |
setCatalog |
设置给定的目录名称,以便选择要在其中工作的此Connection 对象的数据库的子空间。如果驱动程序不支持目录,它会默默地忽略这个请求。 调用 setCatalog 对先前创建或准备的Statement 对象没有影响。 当调用 Connection 方法 prepareStatement 或 prepareCall 时,DBMS 准备操作是否立即发生由实现定义。 为了获得最大的可移植性,应该在创建或准备语句之前调用 setCatalog 。 |
setTransactionIsolation |
尝试将此 Connection 对象的事务隔离级别更改为给定级别。 Connection 接口中定义的常量是可能的事务隔离级别。 |
abort |
终止打开的连接。 调用abort 会导致:1. 标记为关闭的连接 2. 关闭与数据库的任何物理连接 3. 释放连接使用的资源 确保当前正在访问连接的任何线程将继续完成或抛出 SQLException 。调用 abort 标记连接关闭并释放所有资源。 在关闭的连接上调用 abort 是空操作。连接占用的资源的中止和释放可能需要较长时间。 当 abort 方法返回时,连接将被标记为已关闭,作为参数传递给 abort 的执行程序可能仍在执行任务以释放资源。在允许该方法继续之前,此方法会检查是否存在 SQLPermission 对象。 如果存在 SecurityManager 且其 checkPermission 方法拒绝调用中止,则此方法将抛出 java.lang.SecurityException 。 |
可以看到这个接口主要定义了操作数据库相关的动作,而PoolConnection
类只实现了接口中的abort
和close
方法,其他的方法全部被交由父类DelegatingConnection
实现。DelegatingConnection
才是一个真实处理数据库操作的基础连接,而PoolConnection
是对我们初始化的对象池进行管理。而连接池的初始化则是在我们的demo示例中进行手动初始化的。
ObjectPool<PoolableConnection> connectionPool =
new GenericObjectPool<>(poolableConnectionFactory);
poolableConnectionFactory.setPool(connectionPool);
数据库连接属性
属性 | 是否可以设置 | 作用 |
---|---|---|
dataSourceJmxObjectName |
否,由根据不同的驱动包指定 | JMX注册使用,为数据库连接对象的名称。实际调试时可以通过jstack 和jconsole 看到实际连接对象的连接状态 |
validationQuery |
可以 | 在将连接返回给调用者之前,将用于验证来自该池的连接的 SQL 查询。 如果指定,此查询必须是一个返回至少一行的 SQL SELECT 语句。 如果未指定,Connection.isValid(int) 将用于验证连接。 |
validationQueryTimeoutSeconds |
可以,默认-1 | 连接验证查询失败前的超时秒数。 |
connectionInitSqls |
可以 | 这些 SQL 语句在创建连接后运行一次。 例如,此属性可用于在创建连接后仅在 Oracle 数据库中运行一次 ALTER SESSION SET NLS_SORT=XCYECH。 |
defaultReadOnly |
可以,默认false | 连接池创建的连接的默认只读状态。 |
defaultAutoCommit |
可以,默认false | 连接池创建的连接的默认自动提交状态。 |
defaultTransactionIsolation |
可以,默认-1 | 连接池创建的连接的默认 TransactionIsolation 状态。 |
defaultCatalog |
可以 | 连接池创建的连接的默认“目录”。 |
defaultSchema |
可以 | 此池创建的连接的默认“模式”。 |
cacheState |
可以,默认true | 控制池连接是否缓存某些状态而不是查询数据库的当前状态以提高性能的属性。 |
poolPreparedStatements |
可以,默认false | 此池的准备语句池。 当此属性设置为 true 时,PreparedStatements 和 CallableStatements 都被合并。 |
clearStatementPoolOnReturn |
可以,默认flase | 设置当连接返回池时是否清除语句池(通过 setPoolStatements(boolean) 启用) |
maxOpenPreparedStatements |
可以,默认-1 | 可以同时从语句池中分配的最大打开语句数,或者为负数则没有限制。 由于连接通常一次只使用一个或两个语句,因此这主要用于帮助检测资源泄漏。 |
maxConnLifetimeMillis |
可以,默认-1 | 连接最长生存时间 |
fastFailValidation |
可以,默认false | true 表示此工厂创建的连接将快速失败验证 |
disconnectionSqlCodes |
可以 | 断开连接的 SQL 代码。 |
rollbackOnReturn |
可以,默认false | 是否在返回时回滚。 |
autoCommitOnReturn |
可以,默认false | 是否在返回时自动提交。 |
defaultQueryTimeoutSeconds |
可以 | 获设置将用于从此连接创建的语句的默认查询超时。 null 表示将使用驱动程序默认值。 |
评论区