Spring配置数据源

Spring提供了3种配置数据源(DataSource)的Bean的方式,如下所示:

  • 通过JNDI查找的数据源
  • 连接池数据源
  • 由JDBC驱动程序定义的数据源
  • Spring提供的嵌入式数据源

这里不介绍JNDI方式的数据源,只介绍后面三种。

连接池数据源

这里介绍的是第二种数据源配置方式,连接池数据源。Spring并不提供连接池数据源的实现,但是可以使用下面3种第三方的连接池数据源:

  • Apache Commons DBCP
  • c3p0
  • BoneCP

上面说的这3种连接池可以在Spring配置为数据源。接下来介绍各种连接池的配置方式,主要介绍xml和java代码的方式来配置连接池,以及各种连接池的属性。这里说明一下,在xml和java代码方式配置中,只会创建连接池需要的4个要素:驱动名,url,用户名,密码。其他配置根据需要自行添加。这里以MySQL数据库为例来配置数据源。
创建一个Properties文件,用于保存MySql相关的数据

db.driverClass=com.mysql.jdbc.Driver
db.url=jdbc:mysql://a.b.c.com:3306/dbname?useUnicode=true&characterEncoding=UTF-8
db.username=root
db.password=root

Apache Commons DBCP

使用xml配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  destroy-method="close">  
    <property name="driverClassName" value="${db.driverClass}"></property>  
    <property name="url" value="${db.url}"></property>  
    <property name="username" value="${db.username}"></property>  
    <property name="password" value="${db.password}"></property>    
</bean>

使用java配置:

@Bean
public DataSource dataSource() {
    BasicDataSource ds = new BasicDataSource();
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    ds.setUrl("jdbc:mysql://a.b.c.com:3306/dbname?useUnicode=true&characterEncoding=UTF-8");
    ds.setUsername("root");
    ds.setPassword("root");
    return ds;
}

属性介绍:

属性

默认值

解释

initialSize

0

当连接池启动的时候创建的初始连接数量,1.2版本后支持

maxActive

8

最大连接数数,如果为0的话,表示无限制

maxIdle

8

最大空闲连接数,如果值为0的话,表示无限制

minIdle

0

最小空闲连接数,如果0的话,表示不创建

maxOpenPreparedStatements

不限制

statement池能够同时分配的打开的statements的最大数量,0表示不限制

maxWait

无限

无可用连接是的等待时间,单位毫秒,如果值为-1时,表示无限等待;如果超时,则抛出异常

minEvictableIdleTimeMillis

1000 * 60 * 30

连接被收回前的空闲时间,超过这个时间,该连接会被收回,单位毫秒

poolPreparedStatements

false

是否开启池的prepared statement 池功能

更多属性配置请参考官方文档:
DBCP官方属性配置介绍

c3p0

使用XML配置:

<bean id="dataSource"  
    class="com.mchange.v2.c3p0.ComboPooledDataSource"  
    destroy-method="close">  
    <property name="driverClass" value="${db.driverClass}"></property>  
    <property name="jdbcUrl" value="${db.url}"></property>  
    <property name="user" value="${db.username}"></property>  
    <property name="password" value="${db.password}"></property>    
</bean>

使用java配置:

@Bean
public DataSource dataSource() {
    ComboPooledDataSourceds = new ComboPooledDataSource();
    ds.setDriverClass("com.mysql.jdbc.Driver");
    ds.setJdbcUrl("jdbc:mysql://a.b.c.com:3306/dbname?useUnicode=true&characterEncoding=UTF-8");
    ds.setUser("root");
    ds.setPassword("root");
    return ds;
}

属性介绍:

属性

默认值

解释

acquireIncrement

3

当连接池中的连接用完时,C3P0一次性创建新连接的数目

minPoolSize

3

连接池中保留的最小连接数

maxPoolSize

15

连接池中保留的最大连接数

initialPoolSize

3

初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值

maxIdleTime

0

最大空闲时间,超过空闲时间的不在使用的连接将被丢弃。0表示永不丢弃

acquireRetryAttempts

30

定义在从数据库获取新连接失败后重复尝试获取的次数

acquireRetryDelay

1000

两次连接中间隔时间,单位毫秒

maxStatements

0

JDBC的标准参数,用以控制数据源内加载的PreparedStatement数量。但由于预缓存的Statement属 于单个Connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素,如果maxStatements与 maxStatementsPerConnection均为0,则缓存被关闭

maxStatementsPerConnection

0

连接池内单个连接所拥有的最大缓存Statement数

idleConnectionTestPeriod

0

隔多少秒检查所有连接池中的空闲连接

autoCommitOnClose

false

连接关闭时默认将所有未提交的操作回滚

更多属性配置请参考官方文档:
c3p0官方属性配置介绍

BoneCP

使用XML配置:

<bean id="dataSource"  
    class="com.jolbox.bonecp.BoneCPDataSource"  
    destroy-method="close">  
    <property name="driverClass" value="${db.driverClass}"></property>  
    <property name="jdbcUrl" value="${db.url}"></property>  
    <property name="username" value="${db.username}"></property>  
    <property name="password" value="${db.password}"></property>    
</bean>

使用java配置:

@Bean
public DataSource dataSource() {
    BoneCPDataSource= new BoneCPDataSource();
    ds.setDriverClass("com.mysql.jdbc.Driver");
    ds.setJdbcUrl("jdbc:mysql://a.b.c.com:3306/dbname?useUnicode=true&characterEncoding=UTF-8");
    ds.setUsername("root");
    ds.setPassword("root");
    return ds;
}

这种配置连接池数据源的方式用的不是很多,这里就不介绍了,详细属性配置请参考官网
BoneCP官方属性配置介绍

有JDBC驱动程序定义的数据源

这里介绍的是第三种数据源配置方式;在Spring中,配置最简单的数据源就是通过一个JDBC驱动。Spring提供了3个这样的驱动类来配置数据源,分别是:

  • DriverManagerDataSource:每次请求都会返回一个新的数据库连接,与连接池不同的是,返回的连接没有被池化(也就是没有放入到连接池中,当然也没有创建连接池)
  • SimpleDriverDataSource:同DriverManagerDataSource工作方式一样,不同的地方是,它直接使用JDBC驱动克服一下在某些环境下可能出现的类加载的问题,比如在一个OSGi容器
  • SingleConnectionDataSource:每次请求都返回相同的连接,尽管SingeConnectionDataSource不是一个连接池数据源,但是可以认为它是只有一个数据库连接的连接池数据源

使用这种数据源的话,3个驱动类的配置的方式是一样的,只需要将class属性换一下即可。这里就仅介绍一下DriverManagerDataSource
其他属性与DBCP配置一样。与DBCP数据源连接池的区别就是,只需要配置4个基本要素就可。
如下所示:

XML配置方式:

<bean id="dataSource"  
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
    <property name="driverClassName" value="${db.driverClass}"></property>  
    <property name="url" value="${db.url}"></property>  
    <property name="username" value="${db.username}"></property>  
    <property name="password" value="${db.password}"></property>    
</bean>

Java配置方式:

@Bean
    public DataSource driverManagerDataSource(){
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://a.b.c.com:3306/dbname?useUnicode=true&characterEncoding=UTF-8");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }

这种方式配置数据源是有缺陷的,一般不在生产环境中使用这种数据源,SingleConnectionDataSource只有一个连接数,无论是正式环境还是测试环境中,在多线程的应用程序中都不能很好的工作;DriverManagerDataSource和SimpleDriverDataSource虽然能在多线程的应用程序下工作,但是每次请求都会创建出一个连接,会影响应用程序的性能。因为这些限制,所以在一般推荐使用第二种也就是连接池数据源。

Spring提供的嵌入式数据源

大多数数据库都有自己的服务端和客户端,但嵌入式数据库是作为应用程序的一部分;这种数据库不在生产环境中使用,一般使用在开发和测试环境中,因为这种数据库在应用每次重启的时候都会重置所有数据。
Spring提供了对嵌入式数据库的支持,支持如下3种嵌入式数据库:

  • H2
  • HSQL
  • DERBY

现在主要介绍一下如何配置H2嵌入式数据源,其他的方式只需要稍微修改一下即可:

Spring jdbc命名空使配置一个嵌入式数据源很简单,如下xml配置中,显示如何使用jdbc命名空间来配置一个H2嵌入式数据源

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    ...
    <jdbc:embedded-database id="dataSource" type="H2">
    <!--如果是其他嵌入式数据源的话,设置type为HSQL或者DERBY -->
        <jdbc:script location="com/habuma/spitter/db/jdbc/schema.sql"/> 
        <jdbc:script location="com/habuma/spitter/db/jdbc/test-data.sql"/> 
    </jdbc:embedded-database>
    ...
</beans>

使用Java配置方式:

@Bean
public DataSource dataSource() {
//设置其他数据库的话在SetType的时候设置为EmbeddedDatabaseType.HSQL或者EmbeddedDatabaseType.DERBY即可
    return new EmbeddedDatabaseBuilder()
        .setType(EmbeddedDatabaseType.H2)
        .addScript("classpath:schema.sql")
        .addScript("classpath:test-data.sql")
        .build();
}