您的位置 首页 java

说说在 Spring 中如何使用数据源(DBCP、C3P0、JNDI 等)

Spring 中,有以下三种方式来创建数据源:

  1. 通过 JNDI 获取应用服务器中的数据源;
  2. 在 Spring 容器中配置数据源;
  3. 通过代码来创建数据源,这种方式适用于无容器依赖的单元测试。

1 配置数据源

Spring 在第三方依赖包中包含了 2 种数据源的实现包 一个是 Apache 的 DBCP;另一个是 C3P0。 我们可以在 Spring 配置文件中直接配置这些数据源 。

1.1 DBCP

DBCP (Database Connection Pool)是一个依赖 Jakarta commons-pool 对象池机制的数据库连接池,所以在类路径下还必须包括 commons-pool.jar。 下面是使用 DBCP 配置 MySQL 数据源的配置片段:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
 <property name="driverClassName" value="com.mysql. jdbc .Driver" /> 
 <property name="url" value="jdbc:mysql:// localhost :3309/db" /> 
 <property name="username" value="root" /> 
 <property name="password" value="xxxxxx" /> 
</ bean > 
 

BasicDataSource 提供了 close() 方法用于关闭数据源,所以必须设定 destroy-method=”close”, 以便 Spring 容器关闭时,能够正常关闭数据源。

除以上必须的数据源属性外,还有一些常用的属性。

事务属性:

连接数相关属性:

连接监测与维护相关属性:

缓存相关属性:

连接泄露回收相关属性:

假设数据库用的是 MySQL,那么如果数据源配置不当,将可能会发生经典的“8小时问题“。 原因是 MySQL 在默认情况下如果发现一个连接的空闲时间超过 8 小时,那么会在数据库端自动关闭这个连接 。 而数据源并不知道这个连接已经被关闭了,所以当它将这个无用的连接返回给某个 DAO 时, DAO 就会抛出无法获取 connection 的异常 。

DBCP 的 testOnBorrow 默认设置为 true,所以从连接池中取出连接之前会先进行检测,因为不会发生 “8 小时问题 ”。 但如果每次取连接时都进行检测,那么在高并发应用下就会产生性能问题。

因此建议在高并发下,将 testOnBorrow 设置为 false;然后将 testWhileIdle 设置为 true,打开空闲连接回收器;最后把 timeBetweenEvictionRunsMillis 的值设定为小于 8 小时,这样那些被 MySQL 所关闭的空闲连接,就会被清除出去。这样不仅解决了 “8 小时问题 ”,而且还保证了高性能 O(∩_∩)O哈哈~

注意: 因为 MySQL 本身的 interactive-timeout(单位为 s)参数,可以设定空闲连接的过期时间,所以我们要想获取到这个参数值,然后再设定 DBCP 的 timeBetweenEvictionRunsMillis 属性值。

1.2 C3P0

C3P0 是一个开放源代码的 JDBC 数据源实现项目,它实现了 JDBC3 和 JDBC2 扩展规范说明的 Connection 和 Statement 池 。

下面是使用 C3P0 配置 MySql 数据源的配置片段:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
 <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" /> 
 <property name="jdbcUrl" value="jdbc:mysql://localhost:3309/db" /> 
 <property name="use" value="xxx" /> 
 <property name="password" value="xxxxxx" /> 
</bean> 
 

C3P0 也提供了一个用于关闭数据源的 close() 方法,这样我们就可以保证 Spring 容器被关闭时,能够成功关闭数据源 。

2 JNDI 数据源

如果应用配置在高性能的应用服务器(如 WebLogic 或 Websphere 等)上,我们可能更希望使用应用服务器所提供的数据源 。 应用服务器的数据源使用 JNDI 方式来供调用者使用, Spring 为此专门提供了引用 JNDI 资源的 JndiObjectFactoryBean 类 。 下面是一个简单的配置:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
 p:jndiName=" java :comp/env/jdbc/ds"/>
 

Spring2.0+ 为获取 J2EE 资源提供了一个 jee 命名空间,通过 jee 命名空间,可以有效地简化 J2EE 资源的引用:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""
 xmlns:xsi=""
 xmlns:p=""
 xmlns:jee=""
 xsi:schemaLocation=" 
 
 
 ">
 <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/ds"/>
</beans>
 

3 Spring 数据源实现类

Spring 本身也提供了一个简单的数据源实现类 DriverManagerDataSource ,它位于 org.springframework.jdbc.datasource 包中 。 这个类实现了 javax.sql.DataSource 接口,但它并没有提供池化连接机制,每次调用 getConnection() 方法获取新连接时,只是简单地创建一个新的连接 。它不需要额外的依赖类,所以,这个数据源类比较适合在单元测试中使用 。

Spring 数据源实现类既可以通过配置直接使用,也可以在代码中实例化调用:

DriverManagerDataSource dataSource=new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/spring4");
dataSource.setUsername("root");
dataSource.setPassword("");
try {
 Connection connection=dataSource.getConnection();
 if(connection.isClosed()){
 System.out.println("连接已关闭");
 }else{
 System.out.println("连接已开启");
 }
} catch (SQLException e) {
 e.printStackTrace();
}
 

文章来源:智云一二三科技

文章标题:说说在 Spring 中如何使用数据源(DBCP、C3P0、JNDI 等)

文章地址:https://www.zhihuclub.com/192949.shtml

关于作者: 智云科技

热门文章

网站地图