SpringBoot使用编程方式配置DataSource的方法
SpringBoot使用固定算法来扫描和配置DataSource。这使我们可以在默认情况下轻松获得完全配置的DataSource实现。
SpringBoot还会按顺序快速的自动配置连接池(HikariCP,ApacheTomcat或CommonsDBCP),具体取决于路径中的哪些类。
虽然SpringBoot的DataSource自动配置在大多数情况下运行良好,但有时我们需要更高级别的控制,因此我们必须设置自己的DataSource实现,因此忽略自动配置过程。
Maven依赖
总体而言,以编程方式创建DataSource实现非常简单。
为了学习如何实现这一目标,我们将实现一个简单的存储库层,它将对某些JPA实体执行CRUD操作。
我们来看看我们的演示项目的依赖项:
org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 2.4.1 runtime 
我们将使用内存中的H2数据库实例来运行存储库层。通过这样做,我们将能够测试以编程方式配置的DataSource,而无需执行昂贵的数据库操作。
让我们确保在MavenCentral上查看最新版本的spring-boot-starter-data-jpa。
配置DataSource
如果我们坚持使用SpringBoot的DataSource自动配置并以当前状态运行我们的项目,程序将按预期工作。
SpringBoot将为我们完成所有重型基础设施管道。这包括创建H2DataSource实现,该实现将由HikariCP,ApacheTomcat或CommonsDBCP自动处理,并设置内存数据库实例。
此外,我们甚至不需要创建application.properties文件,因为SpringBoot也会提供一些默认的数据库设置。
正如我们之前提到的,有时我们需要更高级别的自定义,因此我们必须以编程方式配置我们自己的DataSource实现。
实现此目的的最简单方法是定义DataSource工厂方法,并将其放在使用@Configuration注解的类中:
@Configuration
publicclassDataSourceConfig{
@Bean
publicDataSourcegetDataSource(){
DataSourceBuilderdataSourceBuilder=DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:mem:test");
dataSourceBuilder.username("SA");
dataSourceBuilder.password("");
returndataSourceBuilder.build();
}
}
在这种情况下,我们使用方便的DataSourceBuilder类-一个简洁的JoshuaBloch构建器模式-以编程方式创建我们的自定义DataSource对象。
这种方法非常好,因为构建器可以使用一些常用属性轻松配置DataSource。此外,它还可以使用底层连接池。
使用application.properties文件外部化DataSource配置
当然,也可以部分外部化我们的DataSource配置。例如,我们可以在工厂方法中定义一些基本的DataSource属性:
@Bean
publicDataSourcegetDataSource(){
DataSourceBuilderdataSourceBuilder=DataSourceBuilder.create();
dataSourceBuilder.username("SA");
dataSourceBuilder.password("");
returndataSourceBuilder.build();
}
并在application.properties文件中指定一些额外的配置:
spring.datasource.url=jdbc:h2:mem:test spring.datasource.driver-class-name=org.h2.Driver
在外部源中定义的属性(例如上面的application.properties文件或通过使用@ConfigurationProperties注解的类)将覆盖JavaAPI中定义的属性。
很明显,通过这种方法,我们不再将DataSource配置设置保存在一个地方。
另一方面,它允许我们保持编译时和运行时配置彼此并很好地分离。
这非常好,因为它允许我们轻松设置绑定点。这样我们可以从其他来源包含不同的DataSource,而无需重构我们的bean工厂方法。
测试DataSource配置
测试我们的自定义DataSource配置非常简单。整个过程归结为创建JPA实体,定义基本存储库接口以及测试存储库层。
- 创建JPA实体
让我们开始定义我们的示例JPA实体类,它将为用户建模:
@Entity
@Table(name="users")
publicclassUser{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
privatelongid;
privateStringname;
privateStringemail;
//standardconstructors/setters/getters/toString
}
- 存储库层
我们需要实现一个基本的存储库层,它允许我们对上面定义的User实体类的实例执行CRUD操作。
由于我们使用的是SpringDataJPA,因此我们不必从头开始创建自己的DAO实现。我们只需要扩展CrudRepository接口获得一个工作的存储库实现:
@Repository publicinterfaceUserRepositoryextendsCrudRepository{} 
- 测试存储库层
最后,我们需要检查我们的编程配置的DataSource是否实际工作。我们可以通过集成测试轻松完成此任务:
@RunWith(SpringRunner.class)
@DataJpaTest
publicclassUserRepositoryIntegrationTest{
@Autowired
privateUserRepositoryuserRepository;
@Test
publicvoidwhenCalledSave_thenCorrectNumberOfUsers(){
userRepository.save(newUser("Bob","bob@domain.com"));
Listusers=(List)userRepository.findAll();
assertThat(users.size()).isEqualTo(1);
}
}
  
UserRepositoryIntegrationTest类是测试用例。它只是运行两个存储库接口的CRUD方法来持久化并查找实体。
请注意,无论我们是否决定以编程方式配置DataSource实现,或将其拆分为Java配置方法和application.properties文件,我们都应该始终获得有效的数据库连接。
- 运行示例应用程序
最后,我们可以使用标准的main()方法运行我们的演示应用程序:
@SpringBootApplication
publicclassApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(Application.class,args);
}
@Bean
publicCommandLineRunnerrun(UserRepositoryuserRepository)throwsException{
return(String[]args)->{
Useruser1=newUser("John","john@domain.com");
Useruser2=newUser("Julie","julie@domain.com");
userRepository.save(user1);
userRepository.save(user2);
userRepository.findAll().forEach(user->System.out.println(user);
};
}
}
我们已经测试了存储库层,因此我们确信我们的DataSource已经成功配置。因此,如果我们运行示例应用程序,我们应该在控制台输出中看到存储在数据库中的User实体列表。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
