# JDBC配置数据库第三方连接池
#### 背景信息
当应用程序需要频繁访问DWS数据库时，使用连接池可以复用数据库连接，减少连接创建和销毁的开销，提升系统性能。但由于DWS当前没有自己的JDBC连接池，且继承于PG的连接池已下线，因此DWS建议使用第三方的**druid** 、**Hikari CP** 、**dbcp2**等连接池。
- JDBC继承于PG的连接池已下线，不推荐使用。
- 下述JDBC和驱动下载哪个版本，连接池参数值如何配置，请根据业务实际情况决定。
 
#### dbcp2连接池配置
1. 下载JDBC驱动包，请参见[下载JDBC或ODBC驱动](https://support.huaweicloud.com/mgtg-dws/dws_01_0032.html)。
   
   - 下载commons-dbcp2驱动包，下载地址：<https://commons.apache.org/dbcp/download_dbcp.cgi>。
   
   - 下载commons-logging驱动包，下载地址：<https://commons.apache.org/proper/commons-logging/download_logging.cgi>。
   
   - 下载commons-pool2驱动包，下载地址：<https://commons.apache.org/proper/commons-pool/download_pool>。
   
   
   
   
2. 将JDBC驱动包和commons-dbcp2、commons-logging、commons-pool2驱动包添加到工程中，配置数据库连接池相关参数。 
   - 如果启用了**removeAbandoned** ，则一个已遗弃的连接将会被连接池回收再利用，在"**(getNumIdle() \< 2) and (getNumActive() \> getMaxTotal() - 3)** "成立时，这个机制将被触发。
     - 例如maxTotal=20，这里有18个活跃连接，1个限制连接，则会触发"**removeAbandoned**"。
     
     - 只有在活动连接超过"**removeAbandonedTimeout**"所指定的秒数内未使用才会被删除（默认为300秒）。
     
     - 遍历一个结果集并不被统计为被使用，创建一个语句，预处理语句，可调用语句或使用它们其中的一个执行查询（使用执行方法中的某一个）会重新设置其父连接的**"lastUsed"**属性。
      
   
   - 如果在高负载的系统中将**"maxIdle"** 的值设置的很低，可能会导致一个新的连接刚刚被创建的时候就立即被关闭了。这是因为活跃的线程及时关闭连接要比那些打开连接的线程要快，导致空闲的连接数大于**"maxIdle"** 。高负载系统中**"maxIdle"**的最合适的配置值取决于应用场景，但是缺省值是一个好的开始点。
   
   
   表1dbcp2连接池参数配置 
   | 参数名                                                                                                | 默认值                        | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   |:---|:---|:---|
   | driverClassName                                                                                   | 填写org.postgresql.Driver | 数据库驱动名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | url                                                                                                | -                        | 连接数据库的URL。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
   | username                                                                                          | -                         | 用户名。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | password                                                                                           | -                         | 密码。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | connectionProperties                                                                               | -                       | 连接参数是在建立一个新连接时发送给JDBC驱动的，字符串的格式必须是**\[参数名=参数值;\]**。 用户名和密码属性是需要明确指出的，所以这两个参数不需要包含在这里。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | defaultAutoCommit                                                                                | -                           | 自动提交。通过当前连接池创建连接的默认为自动提交状态，如果不设置，则**"setAutoCommit"**方法将不被调用。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | defaultReadOnly                                                                                    | -                         | 只读设置。通过当前连接池创建连接的默认为只读状态，如果不设置，则**"setReadOnly"**方法将不被调用。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | defaultTransactionIsolation                                                                      | -                        | 事务隔离级别。 通过这个池创建连接的默认为事务隔离策略，设置值为下列中的某一个： - NONE：无。  - READ_COMMITTED：读已提交。  - READ_UNCOMMITTED：读未提交。  - REPEATABLE_READ：可重复读。  - SERIALIZABLE：可串行化。                                                                                                                                                                                                                                                                                                                                                                                                                       |
   | defaultCatalog                                                                                    | -                         | 通过这个池创建连接的默认为缺省的**catalog**。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | cacheState                                                                                         | true                      | 连接池缓存状态。 设置为true，连接资源池后将在第一次读或写，以及随后写的时候缓存当前的只读状态和自动提交设置。这样就省去了对getter的任何进一步调用时对数据库的额外查询。 如果直接访问底层连接，只读状态或自动提交设置改变缓存值将不会被反映到当前的状态，在这种情况下，应该将该属性设置为false以禁用缓存。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | defaultQueryTimeout                                                                                 | null                     | 查询超时时间。 - 设置为一个整数值，用于在创建Statement时，指定为查询超时时间。  - 设置为null，则使用驱动程序默认设置。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
   | enableAutoCommitOnReturn                                                                           | true                    | 连接归还到池时，设置为自动提交。 如果设置为true，则连接被归还到连接池时，会指定设置为**"autoCommit = true"**。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
   | rollbackOnReturn                                                                                  | true                      | 连接归还到池时，回滚所有操作。 如果设置为true，则连接被归还到连接池时，会自动执行一次**"rollback()"**；前提是自动提交为true。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | initialSize                                                                                        | 0                         | 初始连接数。当前连接池被启动时初始化的创建的连接个数，起始生效版本为1.2版本。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
   | maxTotal                                                                                            | 8                          | 最大活动连接数。可以在当前连接池中同一时刻被分配的有效连接数的最大值，如果设置为负数，则不限制。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
   | maxIdle                                                                                           | 8                         | 最大空闲连接数。在连接池中，可以保持空闲状态的最大连接数，超出设置值之外的空闲连接在归还到连接池时将被释放，如设置为负数，则不限制。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
   | minIdle                                                                                           | 0                          | 最小空闲连接数。可以在池中保持空闲的最小连接数，低于设置值时，空闲连接将被创建，以确保最小空闲连接数大于等于minIdle值；如果设置为0，则不创建。 设置的数值生效的前提是：timeBetweenEvictionRunsMillis（空闲对象驱逐线程运行时的休眠毫秒数）被设置为正数。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
   | maxWaitMillis                                                                                      | -                        | 从连接池获取一个连接时，最大的等待时间。 - 设置为-1时，如果没有可用连接，连接池会一直无限期等待，直到获取到连接为止。  - 设置为N（毫秒）时，则连接池会等待N毫秒，等待不到，抛出异常。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | validationQuery                                                                                    | SELECT 1                  | 确认查询SQL。在连接池返回连接给调用者前用来进行连接校验的查询SQL。 - 如果指定，则这个查询必须是至少返回一行数据的**SELECT**语句。  - 如果没有指定，则连接将通过调用**"isValid()"**方法进行校验。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | validationQueryTimeout                                                                             | -                        | 确认连接有效SQL的执行查询超时时间（秒）。 如果设置为正数，则传递给JDBC驱动的**"setQueryTimeOut()"**方法，这个设置对执行确认有效查询SQL起作用。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | testOnCreate                                                                                      | false                      | 连接创建后，马上验证有效性。指明对象在创建后是否需要验证有效性，如果对象验证失败，则触发对象创建的租借尝试将失败。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | testOnBorrow                                                                                        | true                     | 从连接池获取一个连接时，验证有效性。指明在从池中租借对象时是否要进行验证有效，如果对象验证失败，则对象将从连接池释放，可尝试租借另一个。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | testOnReturn                                                                                      | false                    | 连接被归还到连接池时，验证有效性。指明在将对象归还给连接池前是否需要校验。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | testWhileIdle                                                                                      | false                    | 连接空闲时，验证有效性。指明对象是否需要通过对象驱逐者进行校验（如果有的话），假如一个对象验证失败，该对象将从连接池中释放。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | timeBetweenEvictionRunsMillis                                                                      | -1                         | 空闲对象驱逐线程运行时的休眠毫秒数，如果设置为非正数，不运行空闲对象驱逐线程。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | numTestsPerEvictionRun                                                                              | 3                         | 在每个空闲对象驱逐线程运行过程中进行检查的对象个数。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | minEvictableIdleTimeMillis                                                                         | 1000 \* 60 \* 30         | 符合对象驱逐条件的对象在池中最小空闲毫秒总数。空闲的连接最低需要N毫秒后被释放，单位：毫秒。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | softMinEvictableIdleTimeMillis                                                                      | -1                         | 符合对象驱逐条件的对象在池中最小空闲毫秒总数。 空闲的连接最低需要N毫秒后被释放，但有额外条件，条件是池中至少保留有minIdle所指定的个数的连接。 当**"minEvictableIdleTimeMillis"**被设置为正数时，空闲连接驱逐者首先检测minEvictableIdleTimeMillis，当空闲连接被驱逐者访问时，首先与minEvictableIdleTimeMillis所指定的值进行比较（不考虑当前池中的空闲连接数），然后比较softMinEvictableIdleTimeMillis所指定的连接数，包括minIdle条件。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
   | maxConnLifetimeMillis                                                                            | -1                       | 一个连接的最大存活毫秒数。如果超过这个时间，则连接在下次激活、钝化、校验时都将会失败。如果设置为0或负数，则连接的存活时间是无限的。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
   | logExpiredConnections                                                                                | true                      | 一个过期的连接被连接池关闭时，写日志标识。如果连接存活时间超过maxConnLifetimeMillis，连接将被连接池回收，此时默认输出日志。如果设置为false，则不会写日志。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | connectionInitSqls                                                                                  | -                        | 连接被第一次创建时，执行的初始化SQL。在第一次创建时用来初始化物理连接的SQL语句集合。这些语句只在配置的连接工厂创建连接时被执行一次。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | lifo                                                                                               | true                      | 后进先出。 - 设置为true表明连接池（如果池中有可用的空闲连接时）将返回最后一次使用的租借对象（最后进入）。  - 设置为false则表明池将表现为FIFO队列（先进先出），将会按照它们被归还的顺序从空闲连接实例池中获取连接。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | poolPreparedStatements                                                                            | false                     | 设置该连接池的预处理语句池是否生效。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | maxOpenPreparedStatements                                                                           | -                        | 可以在语句池中同时分配的最大语句数。设置为负数则不限制。 这个设置同时作用于预处理语句池。当一个可用的语句池被创建给每一个连接时，通过以下方法创建的预处理语句将被池化。 ``` public PreparedStatement prepareStatement(String sql) public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) ``` 确保连接会留下一些资源给其他语句。池化预处理语句可能会在数据库中保持他们的游标，可能会引起连接的游标越界，尤其是maxOpenPreparedStatements的值被设置为默认值（无限的），且一个应用程序可能会为每个连接打开大量不同的预处理语句。为了避免这个问题，maxOpenPreparedStatements应该被设置为一个小于连接可以打开的最大游标数的值。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | accessToUnderlyingConnectionAllowed                                                                 | false                      | 控制PoolGuard是否可以访问底层连接。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | removeAbandonedOnMaintenance removeAbandonedOnBorrow | false                     | 标记是否删除超过removeAbandonedTimeout所指定时间的被遗弃的连接。 如果设置为true，则一个连接在超过removeAbandonedTimeout所设定的时间未使用即被认为是应该被抛弃并应该被移除的。 创建一个语句，预处理语句，可调用语句或使用它们的一个执行查询（使用执行方法中的某一个）会重新设置其父连接的lastUsed属性。 在写操作较少的应用程序中将该参数设置为true，可以将数据库连接从连接关闭失败中恢复。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
   | removeAbandonedTimeout                                                                            | 300                       | 一个被抛弃连接可以被移除的超时时间，单位：秒。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
   | logAbandoned                                                                                      | false                   | 标志是否为应用程序中遗弃语句或连接的代码开启日志堆栈追踪。因为一个堆栈跟踪已被创建，被抛弃的语句和连接相关的日志将被覆盖到打开每个连接或者创建一个Statement。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
   | abandonedUsageTracking                                                                           | false                      | 废弃使用跟踪。如果为true，则连接池将每次在池化连接上调用方法时记录堆栈跟踪，并保留最新的堆栈跟踪以帮助调试已放弃的连接。将其设置为true会增加大量开销，请谨慎操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | fastFailValidation                                                                                 | false                    | 验证快速失败。如果发生致命的异常，验证语句会快速失败。而不会再执行"isValid()"，也不再去执行验证查询语句。致命的异常（SQL_STATE）指以下： - 57P01 (ADMIN SHUTDOWN)  - 57P02 (CRASH SHUTDOWN)  - 57P03 (CANNOT CONNECT NOW)  - 01002 (SQL92 disconnect error)  - JZ0C0 (Sybase disconnect error)  - JZ0C1 (Sybase disconnect error)  - Any SQL_STATE code that starts with "08"   需要覆盖异常码，请参考disconnectionSqlCodes。 |
   | disconnectionSqlCodes                                                                           | -                        | 异常码。以逗号分割的SQL_STATE码，**"fastFailValidation"** 为**"true"**时生效。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | jmxName                                                                                            | -                       | 以指定的名称将DataSource注册为**JMX MBean**。该名称必须符合JMX对象名称语法。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | registerConnectionMBean                                                                          | true                    | 注册连接**JMX Mbean**。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
      
   
   
 
#### Hikari CP连接池配置
1. 下载JDBC驱动包，请参见[下载JDBC或ODBC驱动](https://support.huaweicloud.com/mgtg-dws/dws_01_0032.html)。
   
   - 下载HikariCP驱动包，下载地址：<https://mvnrepository.com/artifact/com.zaxxer/HikariCP/4.0.3>。
   
   - 下载slf4j驱动包，下载地址：<https://www.slf4j.org/download.html>。
   
   
   
   
2. 将JDBC驱动包和HikariCP、slf4j驱动包添加到工程中，配置数据库连接池相关参数。 
   表2Hikari CP连接池参数配置 
   | 参数名                      | 默认值                       | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   |:---|:---|:---|
   | driverClassName           | 填写org.postgresql.Driver | 数据库驱动名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
   | jdbcUrl                   | -                       | 连接数据库的URL。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | username                 | -                          | 用户名。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | password                 | -                        | 密码。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | autoCommit                | true                    | 连接返回连接池时，是否自动提交事务。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | connectionTimeout          | 30000                   | 从连接池获取连接的最大超时时间。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   | idleTimeout               | 60000                   | 空闲连接存活的最大时间。只有当**minimumIdle小于maximumPoolSize**时，该设置才生效。 - 空闲连接数**大于minimumIdle**且连接的空闲状态时间大于idleTimeout值时，将把该连接从连接池中删除。  - **0**表示永不超时。                                                                                                                                                   |
   | keepaliveTime             | 0                       | 保持空闲连接可用的检测频率，单位：毫秒。0表示不检测。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | maxLifetime               | 1800000                 | 连接存活的最大时间，单位：毫秒。0表示没有限制。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | connectionTestQuery       | -                        | 连接检测的查询语句。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | minimumIdle                 | 10                      | 最小空闲连接数。为了提高性能，建议不要设置此参数，使连接池为固定大小。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | maximumPoolSize         | 10                        | 最大连接数。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | metricRegistry            | -                        | 该参数仅通过编程配置或IoC容器可用。 该参数用于指定池使用的**"Codahale/Dropwizard MetricRegistry"**实例来记录各种指标。                                                                                                                                                                                                                                                                                                                                                                                                     |
   | healthCheckRegistry        | -                       | 该参数仅通过编程配置或IoC容器可用。 该参数用于指定池使用的**"Codahale/Dropwizard HealthCheckRegistry"**实例来记录健康信息。                                                                                                                                                                                                                                                                                                                                                                                                  |
   | poolName                  | -                        | 连接池名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | initializationFailTimeout | 1                       | 启动连接池时不能成功初始化连接，是否快速失败。 - 大于0时，会尝试获取连接。如果获取时间超过指定时长（connectionTimeout + initializationFailTimeout），不会开启连接池，并抛出异常。  - 等于0时，会尝试获取并验证连接。如果获取成功但验证失败则不开启池，但是如果获取失败还是会开启池。  - 小于0时，直接启动连接池，不进行初始化连接尝试。   |
   | isolateInternalQueries    | false                   | 是否在事务中隔离HikariCP自己的查询。**"autoCommit"** 为**"false"**时，该设置生效。                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
   | allowPoolSuspension       | false                    | 是否允许通过JMX挂起和恢复连接池。挂起时获取连接不会超时，直到连接池恢复。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | readOnly                  | false                     | 连接是否只读。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | registerMbeans            | false                    | 是否开启JMX。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | catalog                    | -                       | 默认的数据库catalog。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
   | connectionInitSql          | -                       | 连接池初始化后执行的SQL。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | transactionIsolation      | -                       | 默认的事务隔离级别。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
   | validationTimeout       | 5000                   | 连接检测的超时时间。必须**大于connectionTimeout** ，最小允许的值为**250**。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | leakDetectionThreshold    | 0                        | 连接可以被借出多久。 超过该时间将打印连接可能泄露的日志，最小允许的值为**2000**，单位：毫秒。                                                                                                                                                                                                                                                                                                                                                                                                                                      |
   | schema                     | -                        | 默认的数据库**schema**。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
   | threadFactory               | -                      | 指定连接池用于创建线程的 java.util.concurrent.ThreadFactory实例。此参数仅通过编程配置或IoC容器可用。                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | scheduledExecutor        | -                          | 指定连接池用于执行定时任务的java.util.concurrent.ScheduledExecutorService实例。此参数仅通过编程配置或IoC容器可用。                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
      
   
   
 
#### Druid连接池配置
1. 下载JDBC驱动包，请参见[下载JDBC或ODBC驱动](https://support.huaweicloud.com/mgtg-dws/dws_01_0032.html)。
   
   下载Druid驱动包，下载地址：<https://druid.apache.org/downloads/>。
   
   
2. 将JDBC驱动包和Druid驱动包添加到工程中，配置数据库连接池相关参数。 
   表3Druid连接池参数配置 
   | 参数名                                      | 默认值                     | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   |:---|:---|:---|
   | url                                       | -                      | 连接数据库的URL。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | username                                 | -                       | 用户名。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | password                                   | -                        | 密码。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
   | driverClassName                         | 填写org.postgresql.Driver | 数据库驱动名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | initialSize                               | 0                     | 初始化时建立物理连接的个数。初始化发生在显式调用init方法，或者第一次getConnection时。                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
   | maxActive                                 | 8                     | 线程池中最大的连接数。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
   | minIdle                                   | 0                       | 线程池最小空闲数。Druid会定期扫描连接数情况，如果扫描的值大于该值就关闭多余的连接数，小于就创建符合要求的连接数；这个参数主要应用于突然有大量请求的时候，创建新的连接数，该操作比较耗时。                                                                                                                                                                                                                                                                                                                                                                                                             |
   | connectTimeout                            | -                      | 连接数据库超时时间，单位：毫秒。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | socketTimeout                            | -                      | socket连接数据库连接超时时间，单位：毫秒。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
   | maxWait                                   | -1                      | 连接池中连接用完时，新的请求等待时间，单位：毫秒。 -1表示无限等待，直到超时为止。                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | poolPreparedStatements                    | false                   | 是否缓存**preparedStatement** ，也就是**PSCache**。PSCache对支持游标的数据库性能提升较大。                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | maxOpenPreparedStatements                  | -                       | 启用**PSCache** ，必须配置**大于0**。 当大于0时，poolPreparedStatements自动触发修改为true。                                                                                                                                                                                                                                                                                                                                                                                         |
   | validationQuery                           | SELECT 1                 | 用来检测连接是否有效的SQL。 如果validationQuery为空，则testOnBorrow、testOnReturn、testWhileIdle这三个参数都不会起作用，因为这三个参数都是通过执行参数validationQuery指定的SQL来验证数据库连接的有效性。                                                                                                                                                                                                                                                                                                                       |
   | testOnBorrow                               | -                      | 申请连接时执行**validationQuery**检测连接是否有效，这个配置可能会降低性能，请谨慎操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | testOnReturn                             | -                     | 归还连接时执行**validationQuery**检测连接是否有效，这个配置可能会降低性能，请谨慎操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   | testWhileIdle                            | true                 | 申请连接的时候检测，建议配置为true，不影响性能，并且保证安全性。如果空闲时间**大于timeBetweenEvictionRunMillis** ，执行**validationQuery**检测连接是否有效不会起作用。                                                                                                                                                                                                                                                                                                                                                                                              |
   | timeBetweenEvictionRunsMillis            | 60s                   | 执行**validationQuery**检测连接是否有效。判断连接池的连接空闲数是否大于minIdle，如果是则关闭多余的连接数，少则会补上（如果当前连接池中某个连接在空闲了timeBetweenEvictionRunsMillis时间后仍然没有使用，则会被物理性关闭掉）。 有两个含义： 1. Destroy线程会检测连接的间隔时间。  2. testWhileIdle的判断依据，详细看testWhileIdle属性的说明。   |
   | minEvictableIdleTimeMillis                | 30min                    | 连接保持空闲而不被驱逐的最长存活时间。Destroy线程中如果检测到当前连接的最后活跃时间和当前时间的差值大于minEvictableIdleTimeMillis，则关闭当前连接。 这个参数和timeBetweenEvictionRunsMillis参数存在冲突，可默认不配置该参数。                                                                                                                                                                                                                                                                                                                  |
   | connectionInitSqls                        | -                    | 物理连接初始化的时候执行SQL。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | exceptionSorter                            | -                     | 当数据库抛出一些不可恢复的异常时，抛弃连接。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
   | filters                                  | -                      | 通过别名的方式配置扩展插件，属性类型是字符串。常用的插件有监控统计用的filter： - **stat**：监控统计。  - **log4j**：日志记录。  - **wall**：防御sql注入。                                                                     |
   | proxyFilters                              | -                      | 类型是List\<com.alibaba.druid,filter.Filter\>，可同时配置filter和proxyFilters，这两个是组合关系。                                                                                                                                                                                                                                                                                                                                                                                                                                |
   | removeAbandoned                          | false                  | 如果连接泄露，是否需要回收泄露的连接。 在getNumActive()快要到getMaxActive()的时候，系统会进行无效的连接回收，回收的连接为removeAbandonedTimeout（默认300秒）中设置的秒数后没有使用的连接； 对于建立时间超过removeAbandonedTimeout的连接强制关闭。                                                                                                                                                                                                                                                                                                 |
   | removeAbandonedTimeout                   | 300s                   | 设置Druid强制回收连接的时限，单位：秒。当程序从连接池中得到连接开始算起，指定连接建立多长时间druid将强制回收该连接。                                                                                                                                                                                                                                                                                                                                                                                                                                              |
   | logAbandoned                             | false                  | 如果回收泄露的连接，是否要打印一条log。 指定触发removeAbandoned的时候，是否记录当前线程的堆栈信息到日志中。                                                                                                                                                                                                                                                                                                                                                                                                |
   | removeAbandonedTimeoutMillis               | 5min                    | 连接回收的超时时间。设置**"removeAbandoned"为"true"**，Druid会定期检查线程池溢出的情况，如果不是运行状态，且超过设置的时间就会被回收。                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | maxEvictableIdleTimeMillis                 | 7hours                  | 最大空闲时间，默认为**7**小时。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
   | maxPoolPrepareStatementPerConnectionSize | 20                     | 每个连接最多缓存的SQL数。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | keepAlive                                 | false                  | 初始化连接池时会填充到**minIdle**的数量。 连接池中的minIdle数量以内的连接，空闲时间超过minEvictableIdleTimeMillis时，则会执行keepAlive操作，打开会一直保持minIdle的数量值。                                                                                                                                                                                                                                                                                                                                         |
   | notFullTimeoutRetryCount                | 0                      | 连接池内借出的连接加上可用连接小于最大连接数时，则进行重试操作次数，默认为0。                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | logSlowSql                                | false                   | 是否打印慢SQL。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
      
   
   
3. Druid连接demo示例。 
   resource目录下新建db.properties文件：
   ```
   # 数据库连接参数
   url=jdbc:postgresql://10.10.0.13:8000/gaussdb
   username=user
   password=pass
   validationQuery=select 1
   validationQueryTimeout=300
   #driverClassName=JDBC驱动名
   driverClassName=org.postgresql.Driver
   # 初始化连接的数量
   initialSize=1
   # 最大连接的数量
   maxActive=20
   #核心线程数，大于该数会释放
   minIdle=10
   ```
   示例代码：
   ```
   import com.alibaba.druid.pool.DruidDataSource;
   import com.alibaba.druid.pool.DruidDataSourceFactory;
   import com.alibaba.druid.pool.DruidPooledConnection;
   import java.io.IOException;
   import java.io.InputStream;
   import java.sql.ResultSet;
   import java.sql.Statement;
   import java.util.Properties;
   public class TestDataSource {
       private static DruidDataSource dataSource;
       public static void main(String[] args) throws Exception {
           Properties properties = loadProperties();
           dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
           dataSource.setTimeBetweenEvictionRunsMillis(50 * 1000);
           dataSource.setRemoveAbandoned(true);
           dataSource.setRemoveAbandonedTimeout(120);
           dataSource.setSocketTimeout(5000);
           dataSource.setConnectTimeout(5000);
           dataSource.setQueryTimeout(5);
           final DruidPooledConnection connection = dataSource.getConnection();
           final Statement statement = connection.createStatement();
           execute(statement);
       }
       public static void execute(Statement statement) {
           ResultSet resultSet = null;
           try {
               resultSet = statement.executeQuery("select 1");
               while (resultSet.next()) {
                   String str = resultSet.getString(1);
                   System.out.println("n1 :" + str);
                   return;
               }
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
       /**
        * 加载配置文件，从配置文件获取参数
        */
       public static Properties loadProperties() {
           InputStream inputStream = TestDataSource.class.getClassLoader().getResourceAsStream("db.properties");
           Properties ps = new Properties();
           try {
               ps.load(inputStream);
           } catch (IOException e) {
               e.printStackTrace();
           }
           return ps;
       }
   }
   ```
   
   
 
#### 相关文档
- 基于JDBC开发流程：[基于JDBC开发](https://support.huaweicloud.com/devg-dws/dws_04_0088.html)
- JDBC常见问题定位及对应报错和问题的处理方法：[JDBC问题定位](https://support.huaweicloud.com/trouble-dws/dws_09_0201.html)
- 造成数据库连接失败的原因及处理方法汇总：[建立数据库连接失败](https://support.huaweicloud.com/trouble-dws/dws_09_0202.html)
 
