我有一个应用程序需要连接到两个数据库,但两个数据库的实体都是重复的。
我设法让应用程序连接并保留两个数据库中的实体,但我必须创建两个存储库,每个数据库一个存储库,而且我发现这种方法不正确。
有一种更好的方法来进行此管理,例如,我创建一个存储库并为其定义应使用的连接,例如基于标志。
第一个数据库配置
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = ["xxx.xxx.domains.portadapter.repository.firstRepository"],
entityManagerFactoryRef = "firstEntityManegerFactory",
transactionManagerRef = "firstTransactionManager"
)
class FirstDatabaseConfiguration {
@Bean(name = ["firstDatasource"])
@ConfigurationProperties(prefix = "first.datasource")
fun dataSource(): DataSource? {
return DataSourceBuilder.create().build()
}
@Bean(name = ["firstEntityManegerFactory"])
fun firstEntityManegerFactory(
builder: EntityManagerFactoryBuilder, @Qualifier("firstDatasource") dataSource: DataSource?
): LocalContainerEntityManagerFactoryBean? {
return builder.dataSource(dataSource).packages("xxx").persistenceUnit("xxx")
.build()
}
@Bean(name = ["firstTransactionManager"])
fun firstTransactionManager(
@Qualifier("firstEntityManegerFactory") barEntityManagerFactory: EntityManagerFactory?
): PlatformTransactionManager? {
return JpaTransactionManager(barEntityManagerFactory!!)
}
}
第二个数据库配置
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = ["xxx.xxx.domains.portadapter.repository.secondRepository"],
entityManagerFactoryRef = "secondEntityManegerFactory",
transactionManagerRef = "secondTransactionManeger"
)
class secondDatabaseConfiguration {
@Primary
@Bean(name = ["secondDatasource"])
@ConfigurationProperties(prefix = "spring.datasource")
fun dataSource(): DataSource? {
return DataSourceBuilder.create().build()
}
@Primary
@Bean(name = ["secondEntityManegerFactory"])
fun secondEntityManegerFactory(
builder: EntityManagerFactoryBuilder, @Qualifier("secondDatasource") dataSource: DataSource?
): LocalContainerEntityManagerFactoryBean? {
return builder.dataSource(dataSource).packages("xxx").persistenceUnit("xxx")
.build()
}
@Primary
@Bean(name = ["secondTransactionManager"])
fun secondTransactionManager(
@Qualifier("secondEntityManegerFactory") barEntityManagerFactory: EntityManagerFactory?
): PlatformTransactionManager? {
return JpaTransactionManager(barEntityManagerFactory!!)
}
}
将实体保留在第一个数据库上的年龄组存储库
interface FirstAgeGroupsRepository : JpaRepository<AgeGroups, Int> {
fun findBySispacId(sispacId : String): Optional<AgeGroups>
}
将实体保存在第二个数据库上的年龄组存储库
interface SecondAgeGroupsRepository : JpaRepository<AgeGroups, Int> {
fun findBySispacId(sispacId : String): Optional<AgeGroups>
}
例如,在这个 Controller 中,我必须实例化每个存储库并通过条件定义我应该使用哪个存储库
@Service
class AgeGroupsController(
@Autowired val scoobyAgeGroupRepository: ScoobyAgeGroupsRepository,
@Autowired val fisiaAgeGroupRepository: FisiaAgeGroupsRepository
) {
fun saveAgeGroup(body: AgeGroupDto): ResponseDto {
return try {
val ageGroupFound: Optional<AgeGroups> = fisiaAgeGroupRepository.findBySispacId(body.sispacId)
if (!ageGroupFound.isEmpty) {
return ResponseDto(HttpStatus.FOUND, "Faixa etária ja existe, persistencia não realizada.")
}
val formatter = SimpleDateFormat("yyyy-MM-dd")
val ageGroup = AgeGroups(
body.ageGroupName, formatter.parse(body.createdAt), body.sispacId,
formatter.parse(body.updatedAt)
)
body.ageGroupIndexDescription?.let { ageGroup.setAgeGroupIndexDescription(it) }
fisiaAgeGroupRepository.save(ageGroup)
ResponseDto(HttpStatus.OK, "Faixa etária criada com sucesso!")
} catch (erro: Exception) {
print(erro.message)
ResponseDto(HttpStatus.BAD_REQUEST, erro.message)
}
}
}
如果有人知道任何教程或相关内容可以帮助我改进此代码,因为如果有一天我想添加另一个数据库,我将必须复制存储库,然后在每个 Controller 中再添加一个条件。
我愿意接受建议
最佳答案
将此添加为答案,因为我没有足够的声誉来发表评论。以下是改进此代码的几种方法:
- Spring 使用 Controller /服务/存储库模式。为了使此代码更具可读性/可维护性,请将 Controller 逻辑切入一个单独的
@Service
类。使用 Controller 来实现严格的前端逻辑。一般来说,如果您需要访问代码中的存储库,它很可能属于服务。 - 挑剔:
@Autowired
依赖项可以是私有(private)的
编辑:删除微服务引用
关于java - 用于两个数据库连接的通用 spring 数据存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70597869/