默认数据源HikariDataSource对数据库操作
- 在创建项目时选择JDBC以及MySQL驱动,让SpringBoot自动装配所需组件
创建完成后默认的pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.guih</groupId>
<artifactId>spring-boot-data-jdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-data-jdbc</name>
<description>JDBC Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- SpringBoot集成的JDBC以及数据库连接包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 创建 application.yml 文件,配置连接数据库的参数
spring:
datasource:
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false
- 测试是否能获取到数据源
// 单元测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootDataJdbcApplicationTests {
@Autowired
private DataSource dataSource;
@Test
public void test() throws SQLException {
Connection data = dataSource.getConnection();
System.out.println("------" + data.getClass());
System.out.println("------" + dataSource.getClass());
data.close();
}
}
输出结果如下,数据源获取成功,说明SpringBoot2.1.7默认使用的是Hikari连接池**(SpringBoot2.0之前使用的是tomcat连接池)**
------class com.zaxxer.hikari.pool.HikariProxyConnection
------class com.zaxxer.hikari.HikariDataSource
-
使用数据源对数据库进行操作
-
为了方便测试,这里使用的数据库是本机上的数据库
-
编写代码测试访问数据库
@Controller public class JDBCTest { @Autowired private JdbcTemplate jdbcTemplate; @RequestMapping("/query") @ResponseBody public Map<String, Object> query() { List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT * FROM test1"); return list.get(0); } }
-
启动SpringBoot程序并使用Postman进行测试
SpringBoot默认数据源自动装配原理
-
参考org.springframework.boot.autoconfigure.jdbc包下的DataSourceConfigration类
package org.springframework.boot.autoconfigure.jdbc; import javax.sql.DataSource; import com.zaxxer.hikari.HikariDataSource; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; abstract class DataSourceConfiguration { @SuppressWarnings("unchecked") protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) { return (T) properties.initializeDataSourceBuilder().type(type).build(); } // 根据容器中的情况来进行逻辑判断,添加不同的数据源 @Configuration @ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class) @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true) static class Tomcat { @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; } } @Configuration @ConditionalOnClass(HikariDataSource.class) @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true) static class Hikari { @Bean @ConfigurationProperties(prefix = "spring.datasource.hikari") public HikariDataSource dataSource(DataSourceProperties properties) { HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class); if (StringUtils.hasText(properties.getName())) { dataSource.setPoolName(properties.getName()); } return dataSource; } } // 也可以指定其他的数据源 @Configuration @ConditionalOnClass(org.apache.commons.dbcp2.BasicDataSource.class) @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp2.BasicDataSource", matchIfMissing = true) static class Dbcp2 { @Bean @ConfigurationProperties(prefix = "spring.datasource.dbcp2") public org.apache.commons.dbcp2.BasicDataSource dataSource(DataSourceProperties properties) { return createDataSource(properties, org.apache.commons.dbcp2.BasicDataSource.class); } } @Configuration @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type") static class Generic { @Bean public DataSource dataSource(DataSourceProperties properties) { // 使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性 return properties.initializeDataSourceBuilder().build(); } } }
从代码中可以看出SpringBoot是根据用户的配置来自动配置不同的数据源,目前支持的数据源有以下三种
com.zaxxer.hikari.HikariDataSource (Spring Boot 2.0 以上,默认使用此数据源) org.apache.tomcat.jdbc.pool.DataSource org.apache.commons.dbcp2.BasicDataSource
还可以在配置文件中使用 “spring.datasource.type” 属性来配置用户指定的数据源
-
在同一个包下的另一个类 DataSourceInitializer,当我们要在SpringBoot启动时运行sql建表语句或插入数据时就会用得上
// DataSourceInitializer类部分代码 public boolean createSchema() { List<Resource> scripts = getScripts("spring.datasource.schema", this.properties.getSchema(), "schema"); if (!scripts.isEmpty()) { if (!isEnabled()) { logger.debug("Initialization disabled (not running DDL scripts)"); return false; } String username = this.properties.getSchemaUsername(); String password = this.properties.getSchemaPassword(); runScripts(scripts, username, password); } return !scripts.isEmpty(); } public void initSchema() { List<Resource> scripts = getScripts("spring.datasource.data", this.properties.getData(), "data"); if (!scripts.isEmpty()) { if (!isEnabled()) { logger.debug("Initialization disabled (not running data scripts)"); return; } String username = this.properties.getDataUsername(); String password = this.properties.getDataPassword(); runScripts(scripts, username, password); } } private void runScripts(List<Resource> resources, String username, String password) { if (resources.isEmpty()) { return; } ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); populator.setContinueOnError(this.properties.isContinueOnError()); populator.setSeparator(this.properties.getSeparator()); if (this.properties.getSqlScriptEncoding() != null) { populator.setSqlScriptEncoding(this.properties.getSqlScriptEncoding().name()); } for (Resource resource : resources) { populator.addScript(resource); } DataSource dataSource = this.dataSource; if (StringUtils.hasText(username) && StringUtils.hasText(password)) { dataSource = DataSourceBuilder.create(this.properties.getClassLoader()) .driverClassName(this.properties.determineDriverClassName()).url(this.properties.determineUrl()) .username(username).password(password).build(); } DatabasePopulatorUtils.execute(populator, dataSource); }
从代码中可以看出SpringBoot会从配置文件中读取 “spring.datasource.schema” 属性用于数据库建表,读取 “spring.datasource.data” 属性用于写入数据,所以在需要程序在创建时运行sql文件可以通过这个参数来配置
-