欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot JPA多数据源配置

程序员文章站 2022-04-27 22:24:37
...

当仅有一个数据源时,SpringBoot会通过自动配置DataSource然后注入到实体工场对象LocalContainerEntityManagerFactoryBean和事务管理对象PlatformTransactionManager中实现JPA配置。配置多数据JPA就是在代码中为各个数据源配置这一过程,整体流程如下:

1、配置主数据源

使用的SpringBoot 版本为2.0.0.RELEASE

/**
 * 扫描spring.datasource.primary开头的配置信息
 *
 * @return 数据源配置信息
 */
@Primary
@Bean(name = "primaryDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSourceProperties dataSourceProperties() {
    return new DataSourceProperties();
}

/**
 * 获取主库数据源对象
 *
 * @param properties 注入名为primaryDataSourceProperties的bean
 * @return 数据源对象
 */
@Primary
@Bean(name = "primaryDataSource")
public DataSource dataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties properties) {
    return properties.initializeDataSourceBuilder().build();
}

/**
 * 该方法仅在需要使用JdbcTemplate对象时选用
 *
 * @param dataSource 注入名为primaryDataSource的bean
 * @return 数据源JdbcTemplate对象
 */
@Primary
@Bean(name = "primaryJdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

@Primary注解作用在于未指定bean名称时,默认使用带有该注解的bean。此处为防止出错,所有bean都直接指出了名称。

2、配置第二数据源

/**
 * 扫描spring.datasource.second开头的配置信息
 *
 * @return 数据源配置信息
 */
@Bean(name = "secondDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSourceProperties dataSourceProperties() {
    return new DataSourceProperties();
}

/**
 * 获取从库数据源对象
 *
 * @param properties 注入名为secondDataSourceProperties的bean
 * @return 数据源对象
 */
@Bean(name = "secondDataSource")
public DataSource dataSource(@Qualifier("secondDataSourceProperties") DataSourceProperties properties) {
    return properties.initializeDataSourceBuilder().build();
}

/**
 * 该方法仅在需要使用JdbcTemplate对象时选用
 *
 * @param dataSource 注入名为secondDataSource的bean
 * @return 数据源JdbcTemplate对象
 */
@Bean(name = "secondJdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("secondDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

与主数据区别在于有无@Primary注解,注入bean时一定要指定bean的名称,否则会使用带有@Primary的默认数据源。

3、配置主数据源JPA

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        // repository包名
        basePackages = "com.gwyon.spring.repository.primary",
        // 实体管理bean名称
        entityManagerFactoryRef = "primaryEntityManagerFactory",
        // 事务管理bean名称
        transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryConfig {
    /**
     * 扫描spring.jpa.primary开头的配置信息
     *
     * @return jpa配置信息
     */
    @Primary
    @Bean(name = "primaryJpaProperties")
    @ConfigurationProperties(prefix = "spring.jpa.primary")
    public JpaProperties jpaProperties() {
        return new JpaProperties();
    }

    /**
     * 获取主库实体管理工厂对象
     *
     * @param primaryDataSource 注入名为primaryDataSource的数据源
     * @param jpaProperties     注入名为primaryJpaProperties的jpa配置信息
     * @param builder           注入EntityManagerFactoryBuilder
     * @return 实体管理工厂对象
     */
    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("primaryDataSource") DataSource primaryDataSource
            , @Qualifier("primaryJpaProperties") JpaProperties jpaProperties, EntityManagerFactoryBuilder builder) {
        return builder
                // 设置数据源
                .dataSource(primaryDataSource)
                // 设置jpa配置
                .properties(jpaProperties.getProperties())
                // 设置hibernate配置
                .properties(jpaProperties.getHibernateProperties(new HibernateSettings()))
                // 设置实体包名
                .packages("com.gwyon.spring.entity.primary")
                // 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    /**
     * 获取实体管理对象
     *
     * @param factory 注入名为primaryEntityManagerFactory的bean
     * @return 实体管理对象
     */
    @Primary
    @Bean(name = "primaryEntityManager")
    public EntityManager entityManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
        return factory.createEntityManager();
    }

    /**
     * 获取主库事务管理对象
     *
     * @param factory 注入名为primaryEntityManagerFactory的bean
     * @return 事务管理对象
     */
    @Primary
    @Bean(name = "primaryTransactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
        return new JpaTransactionManager(factory);
    }
}

4、配置第二数据源JPA

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        // repository包名
        basePackages = "com.gwyon.spring.repository.second",
        // 实体管理bean名称
        entityManagerFactoryRef = "secondEntityManagerFactory",
        // 事务管理bean名称
        transactionManagerRef = "secondTransactionManager"
)
public class SecondConfig {
    /**
     * 扫描spring.jpa.second开头的配置信息
     *
     * @return jpa配置信息
     */
    @Bean(name = "secondJpaProperties")
    @ConfigurationProperties(prefix = "spring.jpa.second")
    public JpaProperties jpaProperties() {
        return new JpaProperties();
    }

    /**
     * 获取从库实体管理工厂对象
     *
     * @param secondDataSource 注入名为secondDataSource的数据源
     * @param jpaProperties    注入名为secondJpaProperties的jpa配置信息
     * @param builder          注入EntityManagerFactoryBuilder
     * @return 实体管理工厂对象
     */
    @Bean(name = "secondEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("secondDataSource") DataSource secondDataSource
            , @Qualifier("secondJpaProperties") JpaProperties jpaProperties, EntityManagerFactoryBuilder builder) {
        return builder
                // 设置数据源
                .dataSource(secondDataSource)
                // 设置jpa配置
                .properties(jpaProperties.getProperties())
                // 设置hibernate配置
                .properties(jpaProperties.getHibernateProperties(new HibernateSettings()))
                // 设置实体包名
                .packages("com.gwyon.spring.entity.second")
                // 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
                .persistenceUnit("secondPersistenceUnit")
                .build();
    }

    /**
     * 获取实体管理对象
     *
     * @param factory 注入名为secondEntityManagerFactory的bean
     * @return 实体管理对象
     */
    @Bean(name = "secondEntityManager")
    public EntityManager entityManager(@Qualifier("secondEntityManagerFactory") EntityManagerFactory factory) {
        return factory.createEntityManager();
    }

    /**
     * 获取从库事务管理对象
     *
     * @param factory 注入名为secondEntityManagerFactory的bean
     * @return 事务管理对象
     */
    @Bean(name = "secondTransactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("secondEntityManagerFactory") EntityManagerFactory factory) {
        return new JpaTransactionManager(factory);
    }
}

5、数据库配置信息

#primary数据源配置
spring.datasource.primary.url=jdbc:mysql://127.0.0.1:3306/primary
spring.datasource.primary.username=root
spring.datasource.primary.password=sql123456
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
#primary数据源jpa配置,部分配置仅在此处生效
spring.jpa.primary.show-sql=true
spring.jpa.primary.generate-ddl=true
spring.jpa.primary.hibernate.ddl-auto=update
spring.jpa.primary.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
#second数据源配置
spring.datasource.second.url=jdbc:mysql://127.0.0.1:3306/second
spring.datasource.second.username=root
spring.datasource.second.password=sql123456
spring.datasource.second.driver-class-name=com.mysql.jdbc.Driver
#second数据源jpa配置
spring.jpa.second.generate-ddl=true
spring.jpa.second.hibernate.ddl-auto=update
spring.jpa.second.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

将实体和repository放入相应包下即可关联到相应数据库,点此查看部分代码。

参考: