数据源,简单理解为数据源头,提供了应用程序所须要数据的位置。数据源保证了应用程序与目标数据之间交互的规范和协议,它能够是数据库,文件系统等等。其中数据源定义了位置信息,用户验证信息和交互时所需的一些特性的配置,同时它封装了如何创建与数据源的链接,向外暴露获取链接的接口。应用程序链接数据库无需关注其底层是如何如何创建的,也就是说应用业务逻辑与链接数据库操做是松耦合的。 如下只讨论当数据源为数据库的状况,且为Java环境下JDBC规范下的如何创建与数据库的链接,其余状况相似。html
JDBC(Java DataBase Connectivity, 简称JDBC)是Java中用于规范应用程序如何来访问数据库的应用程序接口(API),它提供了查询和更新数据库中数据的方法。
在基于Java的应用程序中,咱们须要使用JDBC驱动程序与数据库进行交互,其中最重要的一步就是获取与数据库的链接。在传统的JDBC时代,咱们一般写一个通用的方法来封装与数据库的创建操做:java
public Connection getConnection() throws SQLException {
Connection conn = null;
Properties connectionProps = new Properties();
connectionProps.put("user", this.userName);
connectionProps.put("password", this.password);
//获取获取链接
conn = DriverManager.getConnection(
"jdbc:" + this.dbms + "://" +
this.serverName +
":" + this.portNumber + "/",
connectionProps);
return conn;
}
复制代码
以上的代码对于早些的程序员是再熟悉不过了,咱们利用驱动管理器为应用程序提供数据库链接,虽然使用形式简单,但有个很大的问题就是:程序员须要本身去写创建链接的操做,且该方法已经与咱们的应用程序是紧耦合的,在后续须要更改数据库时,须要程序员手动修改这里。在面对多数据源的状况下,该方法可能变成了简单工厂模式那种慵懒的样子,不符合设计模式中“对修改关闭,对扩展开放”的原则。mysql
数据源是对数据库以及对数据库交互操做的抽象,它封装了目标源的位置信息,验证信息和创建与关闭链接的操做。数据源能够看作程序中一个组件,它把传统中须要在代码里编写配置信息和获取链接等操做抽象出一个规范或者接口,这样不一样的第三方能够自行实现该接口提供不一样的策略。这样,数据源就是对应用程序是透明的,开发者只需为应用程序配置特定的数据源便可与数据库进行链接等操做。当须要更换数据库服务器或者更换数据库种类时,只需修改配置中信息便可,无需修改程序代码。
数据源大体分为2种:不提供链接池和提供链接池管理。程序员
Spring中提供的数据源就是不提供链接池功能的,好比DriverManagerDataSource。该数据源对于应用程序的每个链接请求都创建新的链接,当应用程序使用完毕后,再执行销毁操做。当与数据库交互频繁时,这种模式会严重影响程序的性能。时间和空间消耗大多数消耗在链接和销毁中,而非数据库处理。因此Spring建议咱们仅在测试中使用该数据源。如下为原话:web
Only use the DriverManagerDataSource class should only be used for testing purposes since it does not provide pooling and will perform poorly when multiple requests for a connection are made.算法
提供链接池的数据源则是第三方提供的,比较流行的有Apache Jakarta Commons DBCP and C3P0。Spring中并不提供带池化管理的数据源,它的目的在于集成市面上优秀的数据源组件。这里,提个插曲,Spring的口号就是不与市场上优秀的第三方组件竞争,而是以包容的心态为他们提供平台,方便开发者使用它们。
链接池是一种建立和管理一组链接对象的技术,这些链接对象可供任何须要它的线程使用。链接池能够极大地提升Java应用程序的性能,避免了建立新的链接实例时所必需的初始化和认证时间,同时减小总体资源使用,能够大大提升并发web的响应速度。这种数据源会在初始化的时候根据用户配置创建一组链接。当应用程序与数据库交互时,就能够快速从链接池中选择一个空闲的链接使用;当使用完毕,把该链接归还给链接池便可。spring
这里仅仅展现一下如何配置C3P0 数据源。sql
在类路径下的spring中配置文件中,加入如下代码便可,其中jdbc.properties则是一些配置信息。数据库
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<context:property-placeholder location="jdbc.properties"/>
复制代码
固然也能够经过Java代码来配置,使用Spring的注解@Configuration来定义配置类,这样在IOC容器初始化时会实例化该数据源。设计模式
package com.specialyang.questionanswer.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.jboss.C3P0PooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
/** * Created by Special on 2018/8/9 15:32 */
@Configuration
public class DataSourceConfiguration {
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
dataSource.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
dataSource.setUser("swaldman");
dataSource.setPassword("test-password");
return dataSource;
}
}
复制代码
咱们知道SpringBoot中是约定优于配置,springboot提供了不少自动化配置的操做,大大简化了开发者在配置上花费的时间。好比数据源,基于版本2.1.0,SpringBoot采用如下算法来自动化配置数据源:
以上都是在没有显示配置数据源的状况进行的步骤,若手动显示配置了指定数据源,则以上步骤失效。
通常状况下,springboot都是采用HikariCP来做为默认的数据源。
那么如何更改默认的数据源呢?
若是咱们想定义特定的数据源,一种简单的方法就是直接在application.properties指定:
//指定使用c3p0, 固然你须要添加该数据源的依赖包,由于springboot不默认提供
spring.datasource.type=com.mchange.v2.c3p0.ComboPooledDataSource
复制代码
另外一种就是使用上面写的配置类。
Loading class
com.mysql.jdbc.Driver
. This is deprecated. The new driver class iscom.mysql.cj.jdbc.Driver
. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
上面说的已经很清楚了,com.mysql.jdbc.Driver
已经被废弃,要使用新的jdbc驱动程序:com.mysql.cj.jdbc.Driver
,而且该驱动能够被自动加载,手动加载是不必的。因此咱们的application.properties无需在为mysql指定驱动类了。 以上能够在JDBC官方文档找到答案:
When this class first attempts to establish a connection, it automatically loads any JDBC 4.0 drivers found within the class path. Note that your application must manually load any JDBC drivers prior to version 4.0.
[1]docs.spring.io/spring-boot…
[2]docs.oracle.com/javase/tuto…
[3]dev.mysql.com/doc/connect…