javascript
Spring Data JPA 从入门到精通~默认数据源的讲解
默認數據源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false spring.datasource.username=root spring.datasource.password=123456但是在實際工作中不可能這么簡單,因為會用其他數據源,而不是用的默認數據源。我們先來一步一步了解一下,一起來開啟探索它默認的數據源之旅吧。
通過三種方法來查看默認的 DataSource 是什么
(1)日志法:在 application.properties 增加如下配置
logging.level.org.springframework=DEBUG
然后當我們啟動成功之后,通過開發工具 Intellij IDEA 的 Debug 的 Console 控制臺,搜索“DataSource”,找到了如下日志,發現它默認是 JDBC 的 Pool 的 DataSource。
spring.datasource.type=com.zaxxer.hikari.HikariDataSource,需要注意的是這是 Spring Boot 2.0 里面的新特性,代替了 1.5** 版本里面的 org.apache.tomcat.jdbc.pool.DataSource 的數據源,hikari 的口碑可以性能測試行業內的口碑逐漸代替了 Tomcat 的 datasource。
(2)Debug 方法:在 manager 里面的如下代碼
在“userRepository.findByLastName(names);” 設置一個斷點,然后請求一個 URL 讓斷點進來,然后通過開發工具 Intellij IDEA 的 Debug 的 Memory View 視圖,里面搜索
也能發現 DataSource,然后雙擊就能看到我們想看的內容。
(3)最原理的方法、最常用的、原理分析方法
回到 QuickStartApplication,單擊 @SpringBootApplication 查看其源碼關鍵部分如下:
@SpringBootConfiguration@EnableAutoConfigurationpublic @interface SpringBootApplication {......}打開 @EnableAutoConfiguration 所在 JAR 包,打開 spring-boot-autoconfigure-2.0.0.RELEASE.jar/META-INF/spring.factories 文件,發現如下內容:
//# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ ...... org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration打開 JpaRepositoriesAutoConfiguration 類,內容如下: @Configuration @ConditionalOnBean(DataSource.class) @ConditionalOnClass(JpaRepository.class) @ConditionalOnMissingBean({ JpaRepositoryFactoryBean.class,JpaRepositoryConfigExtension.class }) @ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", havingValue = "true", matchIfMissing = true) @Import(JpaRepositoriesAutoConfigureRegistrar.class) @AutoConfigureAfter(HibernateJpaAutoConfiguration.class) public class JpaRepositoriesAutoConfiguration { }這時候可以發現,如果使用了 Spring Boot 的注解方式和傳統的 XML 配置方式是有優先級的,如果配置了 XML 中的 JpaRepositoryFactoryBean,那么就會沿用 XML 配置的一整套,而通過 @ConditionalOnMissingBean 這個注解來判斷,就不會加載 Spring Boot 的 JpaRepositoriesAutoConfiguration 此類的配置,還有就是前提條件 DataSource 和 JpaRepository 必須有相關的 Jar 存在。
打開 HibernateJpaAutoConfiguration 類:
@Configuration @ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class }) @Conditional(HibernateEntityManagerCondition.class) @AutoConfigureAfter({ DataSourceAutoConfiguration.class }) public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {......}這個時候發現了 DataSourceAutoConfiguration 的配置類即 datasource 的配置內容有哪些?
打開 DataSourceAutoConfiguration,此時發現了我們最關鍵的類出現了。
@Configuration @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) @EnableConfigurationProperties(DataSourceProperties.class) @Import({ DataSourcePoolMetadataProvidersConfiguration.class,DataSourceInitializationConfiguration.class }) public class DataSourceAutoConfiguration {......}先看 DataSourcePoolMetadataProvidersConfiguration 類吧,內容如下:
@Configuration public class DataSourcePoolMetadataProvidersConfiguration {//tomcat.jdbc.pool.DataSource前提條件需要引入tomcat-jdbc.jar@Configuration@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)static class TomcatDataSourcePoolMetadataProviderConfiguration {@Beanpublic DataSourcePoolMetadataProvider tomcatPoolDataSourceMetadataProvider() {return (dataSource) -> {if (dataSource instanceof org.apache.tomcat.jdbc.pool.DataSource) {return new TomcatDataSourcePoolMetadata((org.apache.tomcat.jdbc.pool.DataSource) dataSource);}return null;};}}//HikariDataSource.class前提需要引入HikariCP-2.7.8.jar@Configuration@ConditionalOnClass(HikariDataSource.class)static class HikariPoolDataSourceMetadataProviderConfiguration {@Beanpublic DataSourcePoolMetadataProvider hikariPoolDataSourceMetadataProvider() {return (dataSource) -> {if (dataSource instanceof HikariDataSource) {return new HikariDataSourcePoolMetadata((HikariDataSource) dataSource);}return null;};}}//CommonsDbcp 數據源,前提也是需要引入CommonsDbcp**.jar@Configuration@ConditionalOnClass(BasicDataSource.class)static class CommonsDbcp2PoolDataSourceMetadataProviderConfiguration {@Beanpublic DataSourcePoolMetadataProvider commonsDbcp2PoolDataSourceMetadataProvider() {return (dataSource) -> {if (dataSource instanceof BasicDataSource) {return new CommonsDbcp2DataSourcePoolMetadata((BasicDataSource) dataSource);}return null;};}} }通過查看它的代碼可發現,Spring Boot 為我們的 DataSource 提供了最常見的三種默認配置:
- HikariDataSource
- Tomcat 的 JDBC
- Apache 的 dbcp
而最終用哪個?就看你引用了哪個 datasoure 的 jar 包了。因為開篇的案例用的是 Spring Boot 2.0 的默認配置,而 2.0 放棄了默認引用的 Tomcat 的容器,而選用了 HikariDataSource 的配置,成為了 Java 語言里面公認的好的 data source,所以默認用的是 Hikari 的 DataSource 及其 HikariDataSourcePoolMetadata 連接池。當我們引用了 Jetty 或者 netty 等容器,連接池和 datasource 的實現方式也會跟著變的。
Datasource 和 JPA 都有哪些配置屬性
我們接著上面的類 DataSourceAutoConfiguration,通過 @EnableConfigurationProperties(DataSourceProperties.class) 找到了 datasource 該如何配置,打開 DataSourceProperties 源碼:
@ConfigurationProperties(prefix = "spring.datasource") public class DataSourcePropertiesimplements BeanClassLoaderAware, EnvironmentAware, InitializingBean { /*** Name of the datasource.*/ private String name = "testdb"; /*** Generate a random datasource name.*/ private boolean generateUniqueName; /*** Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.*/ private String driverClassName; /*** JDBC url of the database.*/ private String url; /*** Login user of the database.*/ private String username; /*** Login password of the database.*/ private String password; /*** JNDI location of the datasource. Class, url, username & password are ignored when* set.*/ private String jndiName; ......//如果還有一些特殊的配置直接看這個類的源碼即可。 }看到了配置數據的關鍵的幾個屬性的配置,及其一共有哪些屬性值可以去配置。@ConfigurationProperties(prefix = "spring.datasource") 這個告訴我們 application.properties 里面的 datasource 相關的配置必須有 spring.datasource 開頭,這樣當啟動的時候 DataSourceProperties 就會自動加載進來 datasource 的一切配置。正如我們前面配置的一樣:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test spring.datasource.username=jack spring.datasource.password=jack123......這里省略了一些其他datasource的key配置。
其實到這里如果自定義配置時也可以學習 Spring Data 的這種 properteis 的加載方式自定義**Properties.java,包括 DataSource 的配置方法,可以借鑒當時寫的framework.jar。
JpaBaseConfiguration
我們回過頭來再來看 HibernateJpaAutoConfiguration 的父類 JpaBaseConfiguration 打開關鍵內容如下:
@EnableConfigurationProperties(JpaProperties.class) @Import(DataSourceInitializedPublisher.Registrar.class) public abstract class JpaBaseConfiguration implements BeanFactoryAware {private final DataSource dataSource;private final JpaProperties properties; ......}這個時候發現了 JpaProperties 類:
@ConfigurationProperties(prefix = "spring.jpa") public class JpaProperties {//jpa原生的一些特殊屬性private Map<String, String> properties = new HashMap<String, String>();//databasePlatform名字,默認和Database一樣。private String databasePlatform;//數據庫平臺MYSQL、DB2、H2......private Database database;//是否根據實體創建Ddlprivate boolean generateDdl = false;//是否顯示sql,默認不顯示private boolean showSql = false;private Hibernate hibernate = new Hibernate(); ...... }此時再打開 Hibernate 類:
public static class Hibernate { private String ddlAuto; /*** Use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE. This is* actually a shortcut for the "hibernate.id.new_generator_mappings" property.* When not specified will default to "false" with Hibernate 5 for back* compatibility.*/ private Boolean useNewIdGeneratorMappings; @NestedConfigurationProperty private final Naming naming = new Naming(); ......//我們看到Hibernate類就這三個屬性。 }再打開 Naming 源碼看一下命名規范:
public static class Naming {private static final String DEFAULT_HIBERNATE4_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy";private static final String DEFAULT_PHYSICAL_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy";private static final String DEFAULT_IMPLICIT_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy";/*** Hibernate 5 implicit naming strategy fully qualified name.*/private String implicitStrategy;/*** Hibernate 5 physical naming strategy fully qualified name.*/private String physicalStrategy;/*** Hibernate 4 naming strategy fully qualified name. Not supported with Hibernate* 5.*/private String strategy; ......}看到這里面 Naming 命名策略,兼容了 Hibernate4 和 Hibernate5 并且給出了默認的策略,后面章節我們做詳細解釋。
所以配置文件中關于 JPA 的配置基本上就這些配置項。
spring.jpa.database-platform=mysql spring.jpa.generate-ddl=false spring.jpa.hibernate.ddl-auto=none spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.type=trace spring.jpa.properties.hibernate.use_sql_comments=true spring.jpa.properties.hibernate.jdbc.batch_size=50Configuration 思路,實戰學習方法
其實在實際工作中,若遇到問題,經常看到開發人員去百度進行狂搜,看看怎么配置的,然后試了了半天發現怎么配置都沒效果。其實這里給大家提供了一個思路,我們在找配置項的時候,看看源碼都支持哪些 key,而這些 key 分別代表什么意思然后再到百度搜索,這樣我們能對癥下藥,正確完美的完成我們的配置文件的配置。
總結
以上是生活随笔為你收集整理的Spring Data JPA 从入门到精通~默认数据源的讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java技术回顾之JNDI--命名和目录
- 下一篇: Effective Java~3. 私有