SpringBoot-默认数据源HikariDataSource对数据库操作及自动装配原理

默认数据源HikariDataSource对数据库操作

  1. 在创建项目时选择JDBC以及MySQL驱动,让SpringBoot自动装配所需组件

[外链图片转存失败(img-QzCfeTn6-1565848669773)(/Users/guih/Desktop/1.png)]

创建完成后默认的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>
  1. 创建 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
  1. 测试是否能获取到数据源
// 单元测试代码
@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
  1. 使用数据源对数据库进行操作

    1. 为了方便测试,这里使用的数据库是本机上的数据库

      [)]

    2. 编写代码测试访问数据库

      @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);
          } 
      }
      
    3. 启动SpringBoot程序并使用Postman进行测试

      [外链图片转存失败(img-Md6eDEJQ-1565848669774)(/Users/guih/Desktop/6.png)]

    SpringBoot默认数据源自动装配原理

    1. 参考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.HikariDataSourceSpring Boot 2.0 以上,默认使用此数据源)
      
      org.apache.tomcat.jdbc.pool.DataSource
      
      org.apache.commons.dbcp2.BasicDataSource
      

      还可以在配置文件中使用 “spring.datasource.type” 属性来配置用户指定的数据源

    2. 在同一个包下的另一个类 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文件可以通过这个参数来配置

猜你喜欢

转载自blog.csdn.net/qq_43842093/article/details/124832590