java - 用于两个数据库连接的通用 spring 数据存储库

标签 java spring spring-boot kotlin spring-data

我有一个应用程序需要连接到两个数据库,但两个数据库的实体都是重复的。

我设法让应用程序连接并保留两个数据库中的实体,但我必须创建两个存储库,每个数据库一个存储库,而且我发现这种方法不正确。

有一种更好的方法来进行此管理,例如,我创建一个存储库并为其定义应使用的连接,例如基于标志。

第一个数据库配置

@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/

相关文章:

java - Spring JDBC 数据驱动更新

spring-boot - Spring 启动2.3.1 : managed beans missing

java - 如何通过加速度传感器移动我的布局?

spring - javax.validation.ConstraintDefinitionException : HV000074 in Spring MVC

java - JsonXContentGenerator 的 Elasticsearch 2.0 NoClassDefFoundError

java - Spring下如何在Jetty服务器上发布CXF webservice?

java - 从命令行运行一个分解的 spring-boot jar

java - Springboot2和oauth

java - 避免 Java 库中 2 个以上相似子类中的重复方法定义

java - 如何找出 Java 中 JSP 标签的名称?