1. 什么是数据源?
DataSource(数据源)
是连接到任何物理数据库的工厂. DriverManager 工具的替代方案。 它使用 URL 和一些凭据来建立数据库连接。
实现 javax.sql.DataSource
接口的对象通常会注册到 JNDI 服务,并且可以使用它的 JNDI 名称来发现。
数据源可用于获取:
- 标准连接对象;
- 可用于连接池的连接;
- 可用于分布式事务和连接池的连接;
2. 配置一个数据源 DataSource
Spring boot 允许以两种方式定义数据源配置,即 Java 配置和属性配置。 在为我们配置 DataSource bean 之前,DataSourceAutoConfiguration 检查类路径上的 DataSource.class(或 EmbeddedDatabaseType.class)和其他一些事情。
2.1. Maven
如果尚未定义,请将 spring-boot-starter-data-jpa 包含到项目中。 这种依赖带来了所有必要的依赖,包括各种数据库的 JDBC 驱动程序,例如 mysql-connector-java 用于连接到 MySQL 数据库。
如果我们计划在某个步骤(例如测试)使用嵌入式数据库,我们可以单独导入 H2 DB。
$title(pom.xml)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.4.1</version>
<scope>runtime</scope>
</dependency>
2.2. application.properties
数据源配置由 application.properties 文件中的外部配置属性 (spring.datasource.*) 提供。
属性配置将配置与应用程序代码分离。 这样,我们甚至可以从配置提供程序系统导入数据源配置。 下面给定的配置显示了 H2、MySQL、Oracle 和 SQL 服务器数据库的示例属性。
我们通常不需要指定 driver-class-name,因为 Spring Boot 可以从 url 中推断出大多数数据库的名称。
# H2
spring.datasource.url=jdbc:h2:file:C:/temp/test
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# MySQL
#spring.datasource.url=jdbc:mysql://localhost:3306/test
#spring.datasource.username=dbuser
#spring.datasource.password=dbpass
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
# Oracle
#spring.datasource.url=jdbc:oracle:thin:@localhost:1521:orcl
#spring.datasource.username=dbuser
#spring.datasource.password=dbpass
#spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
#spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
# SQL Server
#spring.datasource.url=jdbc:sqlserver://localhost;databaseName=springbootdb
#spring.datasource.username=dbuser
#spring.datasource.password=dbpass
#spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
#spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
2.3. DataSource Bean
创建 DataSource bean 的推荐方法是在使用 @Configuration 注释的类中使用 DataSourceBuilder 类。 数据源也使用底层连接池。
$title(JpaConfig.java)
@Configuration
public class JpaConfig {
@Bean
public DataSource getDataSource()
{
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:file:C:/temp/test");
dataSourceBuilder.username("sa");
dataSourceBuilder.password("");
return dataSourceBuilder.build();
}
}
2.4. JNDI DataSource
如果我们将 Spring Boot 应用程序部署到应用程序服务器,我们可能希望使用应用程序服务器的内置功能来配置和管理数据源,并使用 JNDI 访问它。
我们可以使用 spring.datasource.jndi-name 属性来做到这一点。 例如
#JBoss defined datasource using JNDI
spring.datasource.jndi-name = java:jboss/datasources/testDB
3. Connection Pooling 连接池
3.1. HikariCP, tomcat pooling and commons DBCP2
对于要创建的池化数据源,Spring boot 会验证有效的 Driver 类是否可用。 如果我们设置 spring.datasource.driver-class-name 属性,那么提到的驱动程序类必须是可加载的。
自动配置首先尝试查找和配置 HikariCP。 如果 HikariCP 可用,它总是选择它。 否则,如果找到 Tomcat 池,则对其进行配置。
如果 HikariCP 和 Tomcat 池数据源都不可用,并且 Commons DBCP2 可用,则使用它。
spring-boot-starter-data-jpa starter 自动获取对 HikariCP 的依赖。
3.2. Custom settings
还可以通过使用各自的前缀(spring.datasource.hikari.*、spring.datasource.tomcat.* 和 spring.datasource.dbcp2.*)来微调特定于实现的设置。
例如,我们可以使用以下属性来自定义 DBCP2 连接池。
$title(application.properties)
spring.datasource.dbcp2.initial-size = 50
spring.datasource.dbcp2.max-idle = 50
spring.datasource.dbcp2.default-query-timeout = 10000
spring.datasource.dbcp2.default-auto-commit = true
...
4. Spring boot中配置多数据源
要配置多个数据源,请创建您想要的任意数量的 bean 定义,但将 DataSource 实例之一标记为 @Primary,因为未来的各种自动配置都希望能够按类型获得一个。
请记住,如果我们创建您自己的数据源,自动配置会退出。 所以我们负责为所有数据源 bean 提供配置。
$title(JpaConfig.java)
@Configuration
public class JpaConfig {
@Bean(name = "h2DataSource")
public DataSource h2DataSource()
{
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:file:C:/temp/test");
dataSourceBuilder.username("sa");
dataSourceBuilder.password("");
return dataSourceBuilder.build();
}
@Bean(name = "mySqlDataSource")
@Primary
public DataSource mySqlDataSource()
{
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:mysql://localhost/testdb");
dataSourceBuilder.username("dbuser");
dataSourceBuilder.password("dbpass");
return dataSourceBuilder.build();
}
}
在自动装配数据源时,spring boot 将更喜欢主数据源,即“mySqlDataSource”。 要自动装配另一个非主要数据源,请使用 @Qualifier 注释。
Autowire primary datasource (默认加载primary 数据源)
@Autowired
DataSource dataSource;
Autowire NON-primary datasource
@Autowired
@Qualifier("h2DataSource")
DataSource dataSource;
5. 小结
Spring Boot 提供了非常简单的方法来创建数据源 bean – 使用属性配置或使用 java config @Bean。 Spring Boot 提供现成的自动配置以供使用,可以使用 application.properties 文件中的高级选项进一步自定义。
Spring boot 尝试首先查找和配置连接池,然后是 HikariCP,然后是 Tomcat 池,最后是 Commons DBCP2。 HikariCP 内置 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 启动器。
我们可以配置多个数据源,其中之一必须标记为@Primary。 主数据源默认自动装配,其他数据源需要与@Qualifier 注解一起自动装配。
原创文章,作者:jamestackk,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/243824.html