默认数据源
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=50
Configuration 思路,实战学习方法
其实在实际工作中,若遇到问题,经常看到开发人员去百度进行狂搜,看看怎么配置的,然后试了了半天发现怎么配置都没效果。其实这里给大家提供了一个思路,我们在找配置项的时候,看看源码都支持哪些 key,而这些 key 分别代表什么意思然后再到百度搜索,这样我们能对症下药,正确完美的完成我们的配置文件的配置。