1、SpringBoot 2.2.x默認使用的DataSource
SpringBoot 2.2.x版本,默認使用的DataSource是HikariCP,可以直接通過注入DataSource,並打印出打印全限定名,可以查看。
或可以通過查看自動配置源碼,來找到: @SpringBootApplication -> @EnableAutoConfiguration 所在jar包的META-INF/spring.factories中可以找到org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration-> 進入JpaRepositoriesAutoConfiguration后發現需要先配置HibernateJpaAutoConfiguration -> 進入HibernateJpaAutoConfiguration后發現需要先配置DataSourceAutoConfiguration -> 進入DataSourceAutoConfiguration后發現導入了DataSourcePoolMetadataProvidersConfiguration配置,點進入發現SpringBoot為我們提供了三種默認配置,Tomcat提供的jdbc、HikariCP、阿帕奇提供的Dbcp2,使用那個看引入的那個jar包了,通過maven依賴關系可以知道spring-boot-starter-data-jpa中引入了
spring-boot-starter-jdbc,而spring-boot-starter-jdbc中引用的是HikariCP,所以默認使用的是HikariCP。
@Configuration(proxyBeanMethods = false) public class DataSourcePoolMetadataProvidersConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class) static class TomcatDataSourcePoolMetadataProviderConfiguration { @Bean DataSourcePoolMetadataProvider tomcatPoolDataSourceMetadataProvider() { return (dataSource) -> { org.apache.tomcat.jdbc.pool.DataSource tomcatDataSource = DataSourceUnwrapper.unwrap(dataSource, org.apache.tomcat.jdbc.pool.DataSource.class); if (tomcatDataSource != null) { return new TomcatDataSourcePoolMetadata(tomcatDataSource); } return null; }; } } @Configuration(proxyBeanMethods = false) @ConditionalOnClass(HikariDataSource.class) static class HikariPoolDataSourceMetadataProviderConfiguration { @Bean DataSourcePoolMetadataProvider hikariPoolDataSourceMetadataProvider() { return (dataSource) -> { HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(dataSource, HikariDataSource.class); if (hikariDataSource != null) { return new HikariDataSourcePoolMetadata(hikariDataSource); } return null; }; } } @Configuration(proxyBeanMethods = false) @ConditionalOnClass(BasicDataSource.class) static class CommonsDbcp2PoolDataSourceMetadataProviderConfiguration { @Bean DataSourcePoolMetadataProvider commonsDbcp2PoolDataSourceMetadataProvider() { return (dataSource) -> { BasicDataSource dbcpDataSource = DataSourceUnwrapper.unwrap(dataSource, BasicDataSource.class); if (dbcpDataSource != null) { return new CommonsDbcp2DataSourcePoolMetadata(dbcpDataSource); } return null; }; } } }
如果想使用另外兩個連接池,只需要在pom中添加對應的依賴,並在properties中通過spring.datasource.type指定全限定名即可。
2、DataSource的相關配置
我們通過DataSourceAutoConfiguration類上的@EnableConfigurationProperties(DataSourceProperties.class),可以知道相關的配置在DataSourceProperties類中,都是以spring.datasource開頭的屬性配置。
name:數據源的名稱,使用嵌入式數據庫時,默認名稱是testdb。
generateUniqueName:是否生成隨機數據源名稱。
type:要使用的連接池實現的完全限定名。默認情況下,它是從類路徑自動檢測的。
driverClassName:JDBC驅動程序的完全限定名。默認情況下根據URL自動檢測。
url:數據庫的JDBC URL。
username:數據庫登錄用戶名。
password:數據庫登錄密碼。
jndiName:數據源的JNDI位置。設置時將忽略類、url、用戶名和密碼。
initializationMode:使用可用的DDL和DML腳本初始化數據源,默認使用嵌入式數據庫時使用。
platform:要在DDL或DML腳本中使用的平台(例如schema-${Platform}.sql或data-${Platform}.sql)。
schema:DDL腳本資源位置。進行該配置后,每次啟動程序,程序都會運行指定的sql文件,對數據庫的結構進行操作。
schemaUsername:執行DDL腳本的數據庫用戶名。
schemaPassword:執行DDL腳本的數據庫密碼。
data:DML腳本資源位置。進行該配置后,每次啟動程序,程序都會運行定的sql文件,對數據庫的數據操作。
dataUsername:執行DML腳本的數據庫用戶名。
dataPassword:執行DML腳本的數據庫密碼。
continueOnError:如果初始化數據庫時發生錯誤,是否停止。默認false
separator: SQL初始化腳本中的語句分隔符。
sqlScriptEncoding:SQL腳本編碼。
xa:xa相關設置。
3、Spring-Boot中使用druid連接池
阿里的druid連接池使用者很多,而且提供了監控功能,使用起來也很方便。在pom中添加druid-spring-boot-starter依賴即可。主要的類是DruidDataSourceAutoConfigure,里面就配置了一個DruidDataSourceWrapper,兼容了DataSourceProperties的配置。連接池的相關配置可以在DruidDataSource和DruidAbstractDataSource中看到默認的配置。
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid-spring-boot-starter.version}</version> </dependency>
3.1、連接池通用配置
#druid連接池的配置 #初始化連接大小 spring.datasource.druid.initial-size=1 #最小連接數 spring.datasource.druid.min-idle=1 #最大連接數 spring.datasource.druid.max-active=20 #獲取連接等待超時的時間 spring.datasource.druid.max-wait=60000 #間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 spring.datasource.druid.time-between-eviction-runs-millis=60000 #一個連接在池中最小生存的時間,單位是毫秒 spring.datasource.druid.min-evictable-idle-time-millis=300000 #打開PSCache,並且指定每個連接上PSCache的大小 spring.datasource.druid.pool-prepared-statements=true spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20 #如果有initial-size數量較多時,打開會加快應用啟動時間 spring.datasource.druid.async-init=true #監控統計攔截的filters,屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有:監控統計用的filter:stat;日志用的filter:log4j;防御SQL注入的filter:wall spring.datasource.druid.filters=stat
3.2、druid還為我們提供了監控功能,配置如下:
#druid監控配置 #StatViewServlet配置,說明請參考Druid Wiki,配置_StatViewServlet配置 spring.datasource.druid.stat-view-servlet.enabled=true #配置url-pattern來訪問內置監控頁面 spring.datasource.druid.stat-view-servlet.url-pattern=/druid/* #是否允許清空統計數據 spring.datasource.druid.stat-view-servlet.reset-enable=true #用戶名和密碼 spring.datasource.druid.stat-view-servlet.login-username=druid spring.datasource.druid.stat-view-servlet.login-password=druid #白名單,如果allow沒有配置或者為空,則允許所有訪問 #spring.datasource.druid.stat-view-servlet.allow=127.0.0.1 #黑名單,deny優先於allow,如果在deny列表中,就算在allow列表中,也會被拒絕 #spring.datasource.druid.stat-view-servlet.deny=127.0.0.1 # WebStatFilter配置,說明請參考Druid Wiki,配置_配置WebStatFilter spring.datasource.druid.web-stat-filter.enabled=true spring.datasource.druid.web-stat-filter.url-pattern=/* #排除一些不必要的url,比如*.js,/js/*等等 spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/* #session統計功能 spring.datasource.druid.web-stat-filter.session-stat-enable=true #spring.datasource.druid.web-stat-filter.session-stat-max-count= #spring.datasource.druid.web-stat-filter.principal-session-name= #spring.datasource.druid.web-stat-filter.principal-cookie-name= #spring.datasource.druid.web-stat-filter.profile-enable= # Spring監控配置,說明請參考Druid Github Wiki,配置_Druid和Spring關聯監控配置 # Spring監控AOP切入點,如x.y.z.service.*,配置多個英文逗號分隔 spring.datasource.druid.aop-patterns=cn.caofanqi.study.studyspringdatajpa.controller.*
配置后,啟動項目訪問 http://localhost:8080/druid/index.html 如下:
3.3、多數據源配置
application.properties配置文件中添加連接池配置。
#數據源1配置 spring.datasource.druid.one.driver-class-name=com.mysql.jdbc.Driver spring.datasource.druid.one.url=jdbc:mysql://localhost:3306/study-spring-data-jpa1?characterEncoding=UTF-8&useSSL=false spring.datasource.druid.one.username=root spring.datasource.druid.one.password=root spring.datasource.druid.one.initial-size=1 spring.datasource.druid.one.min-idle=1 spring.datasource.druid.one.max-active=10 spring.datasource.druid.one.max-wait=10000 #數據源2配置 spring.datasource.druid.two.driver-class-name=com.mysql.jdbc.Driver spring.datasource.druid.two.url=jdbc:mysql://localhost:3306/study-spring-data-jpa2?characterEncoding=UTF-8&useSSL=false spring.datasource.druid.two.username=root spring.datasource.druid.two.password=root spring.datasource.druid.two.initial-size=2 spring.datasource.druid.two.min-idle=2 spring.datasource.druid.two.max-active=20 spring.datasource.druid.two.max-wait=20000
JavaConfig配置
/** * 多數據源配置 * @author caofanqi */ @Configuration @Profile("multi-datasource") public class MultiDataSourceConfig { @Primary @Bean(initMethod = "init") @ConfigurationProperties("spring.datasource.druid.one") public DataSource dataSourceOne(){ return DruidDataSourceBuilder.create().build(); } @Bean(initMethod = "init") @ConfigurationProperties("spring.datasource.druid.two") public DataSource dataSourceTwo(){ return DruidDataSourceBuilder.create().build(); } }
測試用例:
/** * 多數據源測試 * @author caofanqi */ @SpringBootTest @ActiveProfiles("multi-datasource") class MultiDataSourceConfigTest { @Resource private DruidDataSource dataSourceOne; @Resource private DruidDataSource dataSourceTwo; @Test void testDataSourceOne(){ assertThat(dataSourceOne.getUrl()).isEqualTo("jdbc:mysql://localhost:3306/study-spring-data-jpa1?characterEncoding=UTF-8&useSSL=false"); assertThat(dataSourceOne.getUsername()).isEqualTo("root"); assertThat(dataSourceOne.getPassword()).isEqualTo("root"); assertThat(dataSourceOne.getDriverClassName()).isEqualTo("com.mysql.jdbc.Driver"); assertThat(dataSourceOne.getInitialSize()).isEqualTo(1); assertThat(dataSourceOne.getMinIdle()).isEqualTo(1); assertThat(dataSourceOne.getMaxActive()).isEqualTo(10); assertThat(dataSourceOne.getMaxWait()).isEqualTo(10000); } @Test void testDataSourceTwo() { assertThat(dataSourceTwo.getUrl()).isEqualTo("jdbc:mysql://localhost:3306/study-spring-data-jpa2?characterEncoding=UTF-8&useSSL=false"); assertThat(dataSourceTwo.getUsername()).isEqualTo("root"); assertThat(dataSourceTwo.getPassword()).isEqualTo("root"); assertThat(dataSourceTwo.getDriverClassName()).isEqualTo("com.mysql.jdbc.Driver"); assertThat(dataSourceTwo.getInitialSize()).isEqualTo(2); assertThat(dataSourceTwo.getMinIdle()).isEqualTo(2); assertThat(dataSourceTwo.getMaxActive()).isEqualTo(20); assertThat(dataSourceTwo.getMaxWait()).isEqualTo(20000); } }
更多druid請看 https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
4、Jpa相關屬性配置
主要在JpaProperties和HibernateProperties中。
JpaProperties類:
properties:Jpa提供商的本地屬性。
mappingResources:映射資源(相當於persistence.xml中的“Mapping file”)
databasePlatform:要操作的目標數據庫的名稱,默認情況下自動檢測。也可以使用“Database”枚舉類設置。
database:要操作的目標數據庫,默認情況下自動檢測。也可以使用“databasePlatform”屬性進行設置。
generateDdl:是否在啟動時初始化ddl(根據實體生成表結構),默認不初始化。
showSql:是否打印SQL,默認不顯示。
openInView:注冊OpenEntityManagerInViewInterceptor。在請求的整個處理過程中將JPA EntityManager綁定到線程。
HibernateProperties類:
naming:命名策略。
ddlAuto:DDL模式。這實際上是“hibernate.hbm2ddl.auto”屬性的快捷方式。在使用嵌入式數據庫且未檢測到架構管理器時,默認為“create-drop”。否則,默認為“none”。
useNewIdGeneratorMappings:是否使用Hibernate新的IdentifierGenerator來實現AUTO、TABLE和SEQUENCE。這實際上是“hibernate.id.new_generator_mappings”屬性的快捷方式。未指定時將默認為“true”。
源碼地址:https://github.com/caofanqi/study-spring-data-jpa