javascript
深入理解Spring Boot数据源与连接池原理
- ? Create by yster@foxmail.com 2018-8-2
一:開始
在使用Spring Boot數(shù)據(jù)源之前,我們一般會(huì)導(dǎo)入相關(guān)依賴。其中數(shù)據(jù)源核心依賴就是spring‐boot‐starter‐jdbc
如下
或者你使用的是JPA:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>查看JPA的依賴關(guān)系,如圖,其中已經(jīng)包含JDBC。
二:數(shù)據(jù)源
配置我們的Mysql數(shù)據(jù)庫(kù)連接信息:
spring:datasource:username:?rootpassword:?123456url:?jdbc:mysql://192.168.15.22:3306/jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=falsedriver‐class‐name:?com.mysql.jdbc.Driver1.如何查看當(dāng)前數(shù)據(jù)源?
編寫單元測(cè)試
@RunWith(SpringRunner.class) @SpringBootTest public class RobotsApplicationTests {@AutowiredDataSource dataSource;@Testpublic void test(){System.out.println(dataSource.getClass());}}查看打印:
class org.apache.tomcat.jdbc.pool.DataSource總結(jié)
所以這段配置的效果就是,默認(rèn)是用org.apache.tomcat.jdbc.pool.DataSource作為數(shù)據(jù)源,
且數(shù)據(jù)源的相關(guān)配置都在DataSourceProperties里面,如下:
@ConfigurationProperties(prefix = "spring.datasource") public class DataSourcePropertiesimplements BeanClassLoaderAware, EnvironmentAware, InitializingBean {...private String name = "testdb";private String driverClassName;private String url;private String username;private String password;.....2.自動(dòng)配置原理
找到org.springframework.boot.autoconfigure.jdbc包下的DataSourceConfiguration類
abstract class DataSourceConfiguration {@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true)static class Tomcat extends DataSourceConfiguration {@Bean@ConfigurationProperties(prefix = "spring.datasource.tomcat")public org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties properties) {org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(properties, org.apache.tomcat.jdbc.pool.DataSource.class);DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());String validationQuery = databaseDriver.getValidationQuery();if (validationQuery != null) {dataSource.setTestOnBorrow(true);dataSource.setValidationQuery(validationQuery);}return dataSource;}}......以上就是自動(dòng)配置代碼,原理大概是如果在classpath下存在org.apache.tomcat.jdbc.pool.DataSource.class類,并且在配置文件中指定spring.datasource.type的值為org.apache.tomcat.jdbc.pool.DataSource,或者不寫都會(huì)認(rèn)為可以通過。只有通過才會(huì)進(jìn)入這段配置代碼,才能注入DataSourceBean。
SpringBoot默認(rèn)可以支持;
org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource、當(dāng)然了,除了Tomcat數(shù)據(jù)源依賴自帶,其他都是缺少狀態(tài)。
3.自定義數(shù)據(jù)源
找到這個(gè)類的最下面,如果spring.datasource.type的值不屬于上面的幾個(gè),那么可以自己定義數(shù)據(jù)源:
@ConditionalOnMissingBean(DataSource.class)@ConditionalOnProperty(name = "spring.datasource.type")static class Generic {@Beanpublic DataSource dataSource(DataSourceProperties properties) {//使用DataSourceBuilder創(chuàng)建數(shù)據(jù)源,利用反射創(chuàng)建響應(yīng)type的數(shù)據(jù)源,并且綁定相關(guān)屬性return properties.initializeDataSourceBuilder().build();}}4.自動(dòng)執(zhí)行SQL語(yǔ)句
打開DataSourceAutoConfiguration自動(dòng)配置類,在自動(dòng)配置DataSource時(shí)會(huì)注入DataSourceInitializer,繼續(xù)打開該類,
我們發(fā)現(xiàn)該類有一個(gè)方法被注解@PostConstruct,這個(gè)注解用于需要在依賴注入完成后執(zhí)行任何初始化的方法上。該初始化方法調(diào)用了runSchemaScripts();
該方法的第一句就調(diào)用 getScripts()方法,獲取SQL腳本,如圖:
所以我們想要初始化一些數(shù)據(jù)庫(kù)腳本,可以依照這個(gè)規(guī)則
schema‐*.sql、data‐*.sql例如:
schema.sql,schema‐all.sql;也可以使用如下指定具體位置
??schema: ???‐?classpath:department.sql作用:
1)、runSchemaScripts();運(yùn)行建表語(yǔ)句;
2)、runDataScripts();運(yùn)行插入數(shù)據(jù)的sql語(yǔ)句;
5.操作數(shù)據(jù)庫(kù)
自動(dòng)配置了JdbcTemplate操作數(shù)據(jù)庫(kù),示例:
@RunWith(SpringRunner.class) @SpringBootTest public class RobotsApplicationTests {@AutowiredJdbcTemplate jdbcTemplate;@Testpublic void test(){jdbcTemplate.queryForList("SELECT * FROM user");}}三:連接池
為什么要把數(shù)據(jù)源和連接池放在一起講,因?yàn)楫?dāng)我們使用了如上所述的默認(rèn)數(shù)據(jù)源之后,那么已默認(rèn)啟用了數(shù)據(jù)庫(kù)鏈接池。 換句話說(shuō),你根本不需要關(guān)心連接池,它本來(lái)就有!
1.默認(rèn)連接池規(guī)則
Tomcat7之前,Tomcat本質(zhì)應(yīng)用了DBCP連接池技術(shù)來(lái)實(shí)現(xiàn)的JDBC數(shù)據(jù)源,但在Tomcat7之后,Tomcat提供了新的JDBC連接池方案,作為DBCP的替換或備選方案,解決了許多之前使用DBCP的不利之處,并提高了性能。詳細(xì)請(qǐng)參考:http://wiki.jikexueyuan.com/project/tomcat/tomcat-jdbc-pool.html
Spring Boot為我們準(zhǔn)備了最佳的數(shù)據(jù)庫(kù)連接池方案,只需要在屬性文件(例如application.properties)中配置需要的連接池參數(shù)即可。
在引入spring-boot-starter-jdbc后,內(nèi)部包含了tomcat-jdbc包,里面有tomcat連接池.然后通過自動(dòng)配置DataSourceAutoConfigurer創(chuàng)建DataSource對(duì)象。
SpringBoot創(chuàng)建默認(rèn)DataSource時(shí),規(guī)則如下:
優(yōu)先尋找創(chuàng)建Tomcat連接池
如果沒有Tomcat連接池,會(huì)查找創(chuàng)建HikariCP
如果沒有HikariCP連接池,會(huì)查找創(chuàng)建dbcp
如果沒有dbcp連接池,會(huì)查找創(chuàng)建dbcp2
可以使用spring.datasource.type屬性指定連接池類型
spring.datasource.type=org.apache.commons.dbcp.BasicDataSource
2.控制連接池行為
在數(shù)據(jù)源那一講中,我們已經(jīng)知道Spring data默認(rèn)使用tomcat-jdbc時(shí),所以直接在application.yml增加配置項(xiàng)spring.datasource.tomcat.*來(lái)控制鏈接池的行為。比如如下配置。
spring:datasource:url: jdbc:mysql://localhost:3306/jackieathome?useSSL=falseusername: rootpassword: mypassword# 6.x版本的MySQL JDBC驅(qū)動(dòng)類為com.mysql.cj.jdbc.Driver# 5.X版本的MySQL JDBC驅(qū)動(dòng)類為com.mysql.jdbc.Driverdriver-class-name: com.mysql.cj.jdbc.Drivertomcat:max-wait: 10000max-active: 30test-on-borrow: truemax-idle: 53.Tomcat常用屬性
| defaultAutoCommit | (布爾值)連接池所創(chuàng)建的連接默認(rèn)自動(dòng)提交狀態(tài)。如果未設(shè)置,則默認(rèn)采用 JDBC 驅(qū)動(dòng)的缺省值(如果未設(shè)置,則不會(huì)調(diào)用 setAutoCommit 方法)。 |
| defaultReadOnly | (布爾值)連接池所創(chuàng)建的連接默認(rèn)只讀狀態(tài)。如果未設(shè)置,將不會(huì)調(diào)用 setReadOnly 方法。(有些驅(qū)動(dòng)并不支持只讀模式,比如:informix) |
| defaultTransactionIsolation | (字符串)連接池所創(chuàng)建的連接的默認(rèn)事務(wù)隔離狀態(tài)。取值范圍為:(參考 javadoc) NONE``READ_COMMITTED``READ_UNCOMMITTED``REPEATABLE_READ``SERIALIZABLE 如果未設(shè)置該值,則不會(huì)調(diào)用任何方法,默認(rèn)為 JDBC 驅(qū)動(dòng)。 |
| defaultCatalog | (字符串)連接池所創(chuàng)建的連接的默認(rèn)catalog。 |
| driverClassName | (字符串)所要使用的 JDBC 驅(qū)動(dòng)的完全限定的 Java 類名。該驅(qū)動(dòng)必須能從與 tomcat-jdbc.jar 同樣的類加載器訪問 |
| username | (字符串)傳入 JDBC 驅(qū)動(dòng)以便建立連接的連接用戶名。注意,DataSource.getConnection(username,password)方法默認(rèn)不會(huì)使用傳入該方法內(nèi)的憑證,但會(huì)使用這里的配置信息。可參看 alternateUsernameAllowed 了解更多詳情。 |
| password | (字符串)傳入 JDBC 驅(qū)動(dòng)以便建立連接的連接密碼。注意,DataSource.getConnection(username,password)方法默認(rèn)不會(huì)使用傳入該方法內(nèi)的憑證,但會(huì)使用這里的配置信息。可參看 alternateUsernameAllowed 了解更多詳情。 |
| maxActive | (整形值)池同時(shí)能分配的活躍連接的最大數(shù)目。默認(rèn)為 100。 |
| maxIdle | (整型值)池始終都應(yīng)保留的連接的最大數(shù)目。默認(rèn)為 maxActive:100。會(huì)周期性檢查空閑連接(如果啟用該功能),留滯時(shí)間超過 minEvictableIdleTimeMillis 的空閑連接將會(huì)被釋放。(請(qǐng)參考 testWhileIdle) |
| minIdle | (整型值)池始終都應(yīng)保留的連接的最小數(shù)目。如果驗(yàn)證查詢失敗,則連接池會(huì)縮減該值。默認(rèn)值取自 initialSize:10(請(qǐng)參考 testWhileIdle)。 |
| initialSize | (整型值)連接器啟動(dòng)時(shí)創(chuàng)建的初始連接數(shù)。默認(rèn)為 10。 |
| maxWait | (整型值)在拋出異常之前,連接池等待(沒有可用連接時(shí))返回連接的最長(zhǎng)時(shí)間,以毫秒計(jì)。默認(rèn)為 30000(30 秒) |
| testOnBorrow | (布爾值)默認(rèn)值為 false。從池中借出對(duì)象之前,是否對(duì)其進(jìn)行驗(yàn)證。如果對(duì)象驗(yàn)證失敗,將其從池中清除,再接著去借下一個(gè)。注意:為了讓 true 值生效,validationQuery參數(shù)必須為非空字符串。為了實(shí)現(xiàn)更高效的驗(yàn)證,可以采用 validationInterval。 |
| testOnReturn | (布爾值)默認(rèn)值為 false。將對(duì)象返回池之前,是否對(duì)齊進(jìn)行驗(yàn)證。注意:為了讓 true 值生效,validationQuery參數(shù)必須為非空字符串。 |
| testWhileIdle | (布爾值)是否通過空閑對(duì)象清除者(如果存在的話)驗(yàn)證對(duì)象。如果對(duì)象驗(yàn)證失敗,則將其從池中清除。注意:為了讓 true 值生效,validationQuery 參數(shù)必須為非空字符串。該屬性默認(rèn)值為 false,為了運(yùn)行池的清除/測(cè)試線程,必須設(shè)置該值。(另請(qǐng)參閱 timeBetweenEvictionRunsMillis) |
| validationQuery | (字符串)在將池中連接返回給調(diào)用者之前,用于驗(yàn)證這些連接的 SQL 查詢。如果指定該值,則該查詢不必返回任何數(shù)據(jù),只是不拋出 SQLException 異常。默認(rèn)為 null。實(shí)例值為:SELECT 1(MySQL) select 1 from dual(Oracle) SELECT 1(MySQL Server)。 |
| validationQueryTimeout | (整型值)連接驗(yàn)證失敗前的超時(shí)時(shí)間(以秒計(jì))。通過在執(zhí)行 validationQuery 的語(yǔ)句上調(diào)用 java.sql.Statement.setQueryTimeout(seconds) 來(lái)實(shí)現(xiàn)。池本身并不會(huì)讓查詢超時(shí),完全是由 JDBC 來(lái)強(qiáng)制實(shí)現(xiàn)。若該值小于或等于 0,則禁用該功能。默認(rèn)為 -1。 |
| validatorClassName | (字符串)實(shí)現(xiàn) org.apache.tomcat.jdbc.pool.Validator接口并提供了一個(gè)無(wú)參(可能是隱式的)構(gòu)造函數(shù)的類名。如果指定該值,將通過該類來(lái)創(chuàng)建一個(gè) Validator 實(shí)例來(lái)驗(yàn)證連接,代替任何驗(yàn)證查詢。默認(rèn)為 null,范例值為:com.mycompany.project.SimpleValidator。 |
| timeBetweenEvictionRunsMillis | (整型值)空閑連接驗(yàn)證/清除線程運(yùn)行之間的休眠時(shí)間(以毫秒計(jì))。不能低于 1 秒。該值決定了我們檢查空閑連接、廢棄連接的頻率,以及驗(yàn)證空閑連接的頻率。默認(rèn)為 5000(5 秒) |
| numTestsPerEvictionRun | (整型值)Tomcat JDBC 連接池沒有用到這個(gè)屬性。 |
| minEvictableIdleTimeMillis | (整型值)在被確定應(yīng)被清除之前,對(duì)象在池中保持空閑狀態(tài)的最短時(shí)間(以毫秒計(jì))。默認(rèn)為 60000(60 秒) |
| accessToUnderlyingConnectionAllowed | (布爾值)沒有用到的屬性。可以在歸入池內(nèi)的連接上調(diào)用 unwrap來(lái)訪問。參閱 javax.sql.DataSource 接口的相關(guān)介紹,或者通過反射調(diào)用 getConnection,或者將對(duì)象映射為 javax.sql.PooledConnection。 |
| removeAbandoned | (布爾值)該值為標(biāo)志(Flag)值,表示如果連接時(shí)間超出了 removeAbandonedTimeout,則將清除廢棄連接。如果該值被設(shè)置為 true,則如果連接時(shí)間大于 removeAbandonedTimeout,該連接會(huì)被認(rèn)為是廢棄連接,應(yīng)予以清除。若應(yīng)用關(guān)閉連接失敗時(shí),將該值設(shè)為 true 能夠恢復(fù)該應(yīng)用的數(shù)據(jù)庫(kù)連接。另請(qǐng)參閱 logAbandoned。默認(rèn)值為 false。 |
| removeAbandonedTimeout | (整型值)在廢棄連接(仍在使用)可以被清除之前的超時(shí)秒數(shù)。默認(rèn)為 60(60 秒)。應(yīng)把該值設(shè)定為應(yīng)用可能具有的運(yùn)行時(shí)間最長(zhǎng)的查詢。 |
| logAbandoned | (布爾值)標(biāo)志能夠針對(duì)丟棄連接的應(yīng)用代碼,進(jìn)行堆棧跟蹤記錄。由于生成堆棧跟蹤,對(duì)廢棄連接的日志記錄會(huì)增加每一個(gè)借取連接的開銷。默認(rèn)為 false |
| connectionProperties | (字符串)在建立新連接時(shí),發(fā)送給 JDBC 驅(qū)動(dòng)的連接屬性。字符串格式必須為:[propertyName=property;]*。注意:user 與 password 屬性會(huì)顯式傳入,因此這里并不需要包括它們。默認(rèn)為 null。 |
| poolPreparedStatements | (布爾值)未使用的屬性 |
| maxOpenPreparedStatements | (整型值)未使用的屬性 |
4.Tomcat JDBC 增強(qiáng)屬性
| initSQL | 字符串值。當(dāng)連接第一次創(chuàng)建時(shí),運(yùn)行的自定義查詢。默認(rèn)值為 null。 |
| jdbcInterceptors | 字符串。繼承自類 org.apache.tomcat.jdbc.pool.JdbcInterceptor的子類類名列表,由分號(hào)分隔。關(guān)于格式及范例,可參見下文的配置 JDBC 攔截器。 這些攔截器將會(huì)插入到 java.sql.Connection 對(duì)象的操作隊(duì)列中。 預(yù)定義的攔截器有: org.apache.tomcat.jdbc.pool.interceptor``ConnectionState——記錄自動(dòng)提交、只讀、catalog以及事務(wù)隔離級(jí)別等狀態(tài)。org.apache.tomcat.jdbc.pool.interceptor``StatementFinalizer——記錄打開的語(yǔ)句,并當(dāng)連接返回池后關(guān)閉它們。 有關(guān)更多預(yù)定義攔截器的詳盡描述,可參閱JDBC 攔截器 |
| validationInterval | 長(zhǎng)整型值。為避免過度驗(yàn)證而設(shè)定的頻率時(shí)間值(以秒計(jì))。最多以這種頻率運(yùn)行驗(yàn)證。如果連接應(yīng)該進(jìn)行驗(yàn)證,但卻沒能在此間隔時(shí)間內(nèi)得到驗(yàn)證,則會(huì)重新對(duì)其進(jìn)行驗(yàn)證。默認(rèn)為 30000(30 秒)。 |
| jmxEnabled | 布爾值。是否利用 JMX 注冊(cè)連接池。默認(rèn)為 true。 |
| fairQueue | 布爾值。假如想用真正的 FIFO 方式公平對(duì)待 getConnection 調(diào)用,則取值為 true。對(duì)空閑連接列表將采用 org.apache.tomcat.jdbc.pool.FairBlockingQueue 實(shí)現(xiàn)。默認(rèn)值為 true。如果想使用異步連接獲取功能,則必須使用該標(biāo)志。 設(shè)置該標(biāo)志可保證線程能夠按照連接抵達(dá)順序來(lái)接收連接。 在性能測(cè)試時(shí),鎖及鎖等待的實(shí)現(xiàn)方式有很大差異。當(dāng) fairQueue=true 時(shí),根據(jù)所運(yùn)行的操作系統(tǒng),存在一個(gè)決策過程。假如系統(tǒng)運(yùn)行在 Linux 操作系統(tǒng)(屬性 os.name = linux)上,為了禁止這個(gè) Linux 專有行為,但仍想使用公平隊(duì)列,那么只需在連接池類加載之前,將 org.apache.tomcat.jdbc.pool.FairBlockingQueue.ignoreOS=true添加到系統(tǒng)屬性上。 |
| abandonWhenPercentageFull | 整型值。除非使用中連接的數(shù)目超過 abandonWhenPercentageFull中定義的百分比,否則不會(huì)關(guān)閉并報(bào)告已廢棄的連接(因?yàn)槌瑫r(shí))。取值范圍為 0-100。默認(rèn)值為 0,意味著只要達(dá)到 removeAbandonedTimeout,就應(yīng)關(guān)閉連接。 |
| maxAge | 長(zhǎng)整型值。連接保持時(shí)間(以毫秒計(jì))。當(dāng)連接要返回池中時(shí),連接池會(huì)檢查是否達(dá)到 now - time-when-connected > maxAge 的條件,如果條件達(dá)成,則關(guān)閉該連接,不再將其返回池中。默認(rèn)值為 0,意味著連接將保持開放狀態(tài),在將連接返回池中時(shí),不會(huì)執(zhí)行任何年齡檢查。 |
| useEquals | 布爾值。如果想讓 ProxyConnection 類使用 String.equals,則將該值設(shè)為 true;若想在對(duì)比方法名稱時(shí)使用 ==,則應(yīng)將其設(shè)為 false。該屬性不能用于任何已添加的攔截器中,因?yàn)槟切r截器都是分別配置的。默認(rèn)值為 true。 |
| suspectTimeout | 整型值。超時(shí)時(shí)間(以秒計(jì))。默認(rèn)值為 0。 類似于 removeAbandonedTimeout,但不會(huì)把連接當(dāng)做廢棄連接從而有可能關(guān)閉連接。如果 logAbandoned 設(shè)為 true,它只會(huì)記錄下警告。如果該值小于或等于 0,則不會(huì)執(zhí)行任何懷疑式檢查。如果超時(shí)值大于 0,而連接還沒有被廢棄,或者廢棄檢查被禁用時(shí),才會(huì)執(zhí)行懷疑式檢查。如果某個(gè)連接被懷疑到,則記錄下 WARN 信息并發(fā)送一個(gè) JMX 通知。 |
| rollbackOnReturn | 布爾值。如果 autoCommit==false,那么當(dāng)連接返回池中時(shí),池會(huì)在連接上調(diào)用回滾方法,從而終止事務(wù)。默認(rèn)值為 false。 |
| commitOnReturn | 布爾值。如果 autoCommit==false,那么當(dāng)連接返回池中時(shí),池會(huì)在連接上調(diào)用提交方法,從而完成事務(wù);如果 rollbackOnReturn==true,則忽略該屬性。默認(rèn)值為 false。 |
| alternateUsernameAllowed | 布爾值。出于性能考慮,JDBC 連接池默認(rèn)會(huì)忽略 DataSource.getConnection(username,password)調(diào)用,只返回之前池化的具有全局配置屬性 username 和 password的連接。 但經(jīng)過配置,連接池還可以允許使用不同的憑證來(lái)請(qǐng)求每一個(gè)連接。為了啟用這項(xiàng)在DataSource.getConnection(username,password)調(diào)用中描述的功能,只需將 alternateUsernameAllowed 設(shè)為 true。 如果你請(qǐng)求一個(gè)連接,憑證為 user 1/password 1,而連接之前使用的是 user 2/password 2 憑證,那么連接將被關(guān)閉,重新利用請(qǐng)求的憑證來(lái)開啟。按照這種方式,池的容量始終以全局級(jí)別管理,而不是限于模式(schema)級(jí)別。 默認(rèn)值為 false。 該屬性作為一個(gè)改進(jìn)方案,被添加到了 bug 50025 中。 |
| dataSource | (javax.sql.DataSource)將數(shù)據(jù)源注入連接池,從而使池利用數(shù)據(jù)源來(lái)獲取連接,而不是利用 java.sql.Driver接口來(lái)建立連接。它非常適于使用數(shù)據(jù)源(而非連接字符串)來(lái)池化 XA 連接或者已建立的連接時(shí)。默認(rèn)值為 null。 |
| dataSourceJNDI | 字符串。在 JNDI 中查找的數(shù)據(jù)源的 JNDI 名稱,隨后將用于建立數(shù)據(jù)庫(kù)連接。參看 datasource 屬性的介紹。默認(rèn)值為 null。 |
| useDisposableConnectionFacade | 布爾值。如果希望在連接上放上一個(gè)門面對(duì)象,從而使連接在關(guān)閉后無(wú)法重用,則要將值設(shè)為 true。這能防止線程繼續(xù)引用一個(gè)已被關(guān)閉的連接,并繼續(xù)在連接上查詢。默認(rèn)值為 true。 |
| logValidationErrors | 布爾值。設(shè)為 true 時(shí),能將驗(yàn)證階段的錯(cuò)誤記錄到日志文件中,錯(cuò)誤會(huì)被記錄為 SEVERE。考慮到了向后兼容性,默認(rèn)值為 false。 |
| propagateInterruptState | 布爾值。傳播已中斷的線程(還沒有清除中斷狀態(tài))的中斷狀態(tài)。考慮到了向后兼容性,默認(rèn)值為 false。 |
| ignoreExceptionOnPreLoad | 布爾值。在初始化池時(shí),是否忽略連接創(chuàng)建錯(cuò)誤。取值為 true時(shí)表示忽略;設(shè)為 false 時(shí),拋出異常,從而宣告池初始化失敗。默認(rèn)值為 false。 |
轉(zhuǎn)載于:https://www.cnblogs.com/yueshutong/p/9409295.html
總結(jié)
以上是生活随笔為你收集整理的深入理解Spring Boot数据源与连接池原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle数据库IP访问限制(IP白名
- 下一篇: github的使用教程