吐槽:Spring官网居然没有Spring-Data-Jpa多数据源的文档,也有可能是我没找到

在单数据源中同时使用Spring-Data-JpaMybatis-Plus没有任何问题,但是多数据源时,Mybatis-Plus的多数据源会失效,会一直使用Spring-Data-Jpa的主数据源,无法切换。原因是在配置Spring-Data-Jpa多数据源时,创建的数据源把Mybatis-Plus的动态数据库给覆盖掉了,所以在配置Spring-Data-Jpa时,使用Mybatis-Plus创建的数据源。

比如我有2个数据源,一个叫做yuq,一个叫做art(取名困难症,拿着大佬的框架名字直接用),配置文件

spring:
  datasource:
    dynamic:
      primary: yuq
      strict: false
      datasource:
        yuq:
          driver-class-name: org.h2.Driver
          username: yuq
          password: yuq
          url: jdbc:h2:./db/yuq;AUTO_SERVER=TRUE
        art:
          driver-class-name: org.h2.Driver
          username: yuq
          password: yuq
          url: jdbc:h2:./db/art;AUTO_SERVER=TRUE

配置Spring-Data-Jpa多数据源

@Configuration
@EnableJpaRepositories(
    // entity的报名
    basePackages = ["me.kuku.test.entity.art"], 
    // 创建的entityManagerFactory的方法名
    entityManagerFactoryRef="entityManagerFactoryByArt",
    // 创建的transactionManager的方法名
    transactionManagerRef="transactionManagerByArt"
)
@EnableTransactionManagement
class ArtJpaConfig(
    private val hibernateProperties: HibernateProperties,
    private val jpaProperties: JpaProperties,
    // 依赖注入mybatis-plus的动态数据源,他会把各个数据源以数据库名字为key存在map中
    private val dataSource: DynamicRoutingDataSource
){
//    如果只是Spring-Data-Jpa则不注释
//    @Primary
//    @Bean
//    @ConfigurationProperties(prefix = "spring.datasource.art")
//    fun dataSourceByArt(): HikariDataSource {
//        return HikariDataSource()
//    }

    @Bean
    @Primary
    fun entityManagerFactoryByArt(build: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
        val properties =
            hibernateProperties.determineHibernateProperties(jpaProperties.properties, HibernateSettings())
        // 获取mybatis-plus中的art数据源
        return build.dataSource(dataSource.dataSources["art"])
            // entity的包名
            .packages("me.kuku.test.entity.art")
            .properties(properties)
            .build()
    }

    @Bean
    @Primary
    fun transactionManagerByArt(build: EntityManagerFactoryBuilder): JpaTransactionManager {
        val transactionManager = JpaTransactionManager()
        transactionManager.entityManagerFactory = entityManagerFactoryByArt(build).`object`
        return transactionManager
    }

}

@Configuration
@EnableJpaRepositories(
    basePackages = ["me.kuku.test.entity.yuq"], 
    entityManagerFactoryRef="entityManagerFactoryByYuQ",
    transactionManagerRef="transactionManagerByYuQ"
)
@EnableTransactionManagement
class YuQJpaConfig(
    private val jpaProperties: JpaProperties,
    private val hibernateProperties: HibernateProperties,
    private val dataSource: DynamicRoutingDataSource
){

//    @Bean
//    @ConfigurationProperties(prefix = "spring.datasource.yuq")
//    fun dataSourceByYuQ(): HikariDataSource {
//        return HikariDataSource()
//    }

    @Bean
    fun entityManagerFactoryByYuQ(build: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
        val properties =
            hibernateProperties.determineHibernateProperties(jpaProperties.properties, HibernateSettings())
        return build.dataSource(dataSource.dataSources["yuq"])
            .packages("me.kuku.test.entity.yuq")
            .properties(properties)
            .build()
    }

    @Bean
    fun transactionManagerByYuQ(build: EntityManagerFactoryBuilder): JpaTransactionManager {
        val transactionManager = JpaTransactionManager()
        transactionManager.entityManagerFactory = entityManagerFactoryByYuQ(build).`object`
        return transactionManager
    }

}

于是,对象关系映射

art数据源中的art

@Entity
@Table(name = "art")
@TableName("art")
class ArtEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @TableId(type = IdType.AUTO)
    var id: Int? = null
    var name: String = ""
    var age: Int = 0
}


interface ArtRepository: JpaRepository<ArtEntity, Int>

@DS("art")
interface ArtMapper: BaseMapper<ArtEntity>

yuq数据源中的yuq

@Entity
@Table(name = "yuq")
@TableName("yuq")
class YuQEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @TableId(type = IdType.AUTO)
    var id: Int? = null
    var name: String = ""
    var age: Int = 0
}


interface YuQRepository: JpaRepository<YuQEntity, Int>

@DS("yuq")
interface YuQMapper: BaseMapper<YuQEntity>

注入相对应的repositorymapper即可使用

最后修改:2023 年 02 月 03 日
如果觉得我的文章对你有用,请随意赞赏