Spring之DataSource配置

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();
}
相关推荐
Rust研习社1 小时前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
IT_陈寒1 小时前
JavaScript的闭包把我坑惨了,说好的内存会自动回收呢?
前端·人工智能·后端
CaffeinePro2 小时前
Pydantic深度使用:数据校验、枚举、ORM映射
后端·fastapi
Chenyiax3 小时前
从 Chat 到 Responses:OpenAI API 抽象为什么变了?
后端
MariaH3 小时前
Koa和Express的区别
后端
MariaH3 小时前
Koa框架的使用
后端
luckdewei4 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某5 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy5 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom5 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github