SpringBoot使用编程方式配置DataSource

Spring Boot使用固定算法来扫描和配置DataSource。这使咱们能够在默认状况下轻松得到彻底配置的DataSource实现。html

Spring Boot还会按顺序快速的自动配置链接池(HikariCP, Apache Tomcat或Commons DBCP),具体取决于路径中的哪些类。java

虽然Spring Boot的DataSource自动配置在大多数状况下运行良好,但有时咱们须要更高级别的控制,所以咱们必须设置本身的DataSource实现,所以忽略自动配置过程。算法

Maven依赖


整体而言,以编程方式建立DataSource实现很是简单。spring

为了学习如何实现这一目标,咱们将实现一个简单的存储库层,它将对某些JPA实体执行CRUD操做。sql

咱们来看看咱们的演示项目的依赖项:数据库

<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>
复制代码

咱们将使用内存中的H2数据库实例来运行存储库层。经过这样作,咱们将可以测试以编程方式配置的DataSource,而无需执行昂贵的数据库操做。编程

让咱们确保在Maven Central上查看最新版本的spring-boot-starter-data-jpa。api

配置DataSource


若是咱们坚持使用Spring Boot的DataSource自动配置并以当前状态运行咱们的项目,程序将按预期工做。oracle

**Spring Boot将为咱们完成全部重型基础设施管道。**这包括建立H2 DataSource实现,该实现将由HikariCP,Apache Tomcat或Commons DBCP自动处理,并设置内存数据库实例。app

此外,咱们甚至不须要建立application.properties文件,由于Spring Boot也会提供一些默认的数据库设置。

正如咱们以前提到的,有时咱们须要更高级别的自定义,所以咱们必须以编程方式配置咱们本身的DataSource实现。

实现此目的的最简单方法是定义DataSource工厂方法,并将其放在使用@Configuration注解的类中:

@Configuration
public class DataSourceConfig {
     
    @Bean
    public DataSource getDataSource() {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName("org.h2.Driver");
        dataSourceBuilder.url("jdbc:h2:mem:test");
        dataSourceBuilder.username("SA");
        dataSourceBuilder.password("");
        return dataSourceBuilder.build();
    }
}
复制代码

在这种状况下,咱们使用方便的DataSourceBuilder类 - 一个简洁的Joshua Bloch构建器模式 - 以编程方式建立咱们的自定义DataSource对象。

这种方法很是好,由于构建器可使用一些经常使用属性轻松配置DataSource。此外,它还可使用底层链接池。

使用application.properties文件外部化DataSource配置


固然,也能够部分外部化咱们的DataSource配置。例如,咱们能够在工厂方法中定义一些基本的DataSource属性:

@Bean
public DataSource getDataSource() { 
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); 
    dataSourceBuilder.username("SA"); 
    dataSourceBuilder.password(""); 
    return dataSourceBuilder.build(); 
}
复制代码

并在application.properties文件中指定一些额外的配置:

spring.datasource.url=jdbc:h2:mem:test
spring.datasource.driver-class-name=org.h2.Driver
复制代码

在外部源中定义的属性(例如上面的application.properties文件或经过使用@ConfigurationProperties注解的类)将覆盖Java API中定义的属性。

很明显,经过这种方法,咱们再也不将DataSource配置设置保存在一个地方。

另外一方面,它容许咱们保持编译时和运行时配置彼此并很好地分离。

这很是好,由于它容许咱们轻松设置绑定点。这样咱们能够从其余来源包含不一样的DataSource,而无需重构咱们的bean工厂方法。

测试DataSource配置


测试咱们的自定义DataSource配置很是简单。整个过程归结为建立JPA实体,定义基本存储库接口以及测试存储库层。

  • 建立JPA实体

让咱们开始定义咱们的示例JPA实体类,它将为用户建模:

@Entity
@Table(name = "users")
public class User {
     
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;
    private String email;
 
    // standard constructors / setters / getters / toString
     
}
复制代码
  • 存储库层

咱们须要实现一个基本的存储库层,它容许咱们对上面定义的User实体类的实例执行CRUD操做。

因为咱们使用的是Spring Data JPA,所以咱们没必要从头开始建立本身的DAO实现。咱们只须要扩展CrudRepository接口得到一个工做的存储库实现:

@Repository
public interface UserRepository extends CrudRepository<User, Long> {}
复制代码
  • 测试存储库层

最后,咱们须要检查咱们的编程配置的DataSource是否实际工做。咱们能够经过集成测试轻松完成此任务:

@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryIntegrationTest {
     
    @Autowired
    private UserRepository userRepository;
    
    @Test
    public void whenCalledSave_thenCorrectNumberOfUsers() {
        userRepository.save(new User("Bob", "bob@domain.com"));
        List<User> users = (List<User>) userRepository.findAll();
         
        assertThat(users.size()).isEqualTo(1);
    }    
}
复制代码

UserRepositoryIntegrationTest类是测试用例。它只是运行两个存储库接口的CRUD方法来持久化并查找实体。

请注意,不管咱们是否决定以编程方式配置DataSource实现,或将其拆分为Java配置方法和application.properties文件,咱们都应该始终得到有效的数据库链接。

  • 运行示例应用程序

最后,咱们可使用标准的main()方法运行咱们的演示应用程序:

@SpringBootApplication
public class Application {
 
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
 
    @Bean
    public CommandLineRunner run(UserRepository userRepository) throws Exception {
        return (String[] args) -> {
            User user1 = new User("John", "john@domain.com");
            User user2 = new User("Julie", "julie@domain.com");
            userRepository.save(user1);
            userRepository.save(user2);
            userRepository.findAll().forEach(user -> System.out.println(user);
        };
    }
}
复制代码

咱们已经测试了存储库层,所以咱们确信咱们的DataSource已经成功配置。所以,若是咱们运行示例应用程序,咱们应该在控制台输出中看到存储在数据库中的User实体列表。

相关文章
相关标签/搜索