數據源,簡單理解爲數據源頭,提供了應用程序所須要數據的位置。數據源保證了應用程序與目標數據之間交互的規範和協議,它能夠是數據庫,文件系統等等。其中數據源定義了位置信息,用戶驗證信息和交互時所需的一些特性的配置,同時它封裝瞭如何創建與數據源的鏈接,向外暴露獲取鏈接的接口。應用程序鏈接數據庫無需關注其底層是如何如何創建的,也就是說應用業務邏輯與鏈接數據庫操做是鬆耦合的。 如下只討論當數據源爲數據庫的狀況,且爲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…