当前位置:   article > 正文

Spring boot 2.3 + Spring Data JPA配置多数据源_org.springframework.boot.orm.jpa.entitymanagerfact

org.springframework.boot.orm.jpa.entitymanagerfactorybuilder

项目近期有个需求,要同时连接两个数据库,并且不同环境,数据库种类还不同,我们有两个数据库,其中一个测试环境是oracle,生产环境又是postgre,另一个一直是postgre,调查了网上能搜到很多资料,基本上写法都一致,比如https://blog.csdn.net/itguangit/article/details/78747969,但用在sb 2.3上会发现两个问题,一个是EntityManagerFactoryBuilder在启动时无法自动注入,虽然理论上sb会自动创建其实例,另一个是2.3中jpaProperties已经没有getHibernateProperties这个方法了,花了两天时间,发现一个外国人写的帖子方法是适用于2.3这个版本的,发布时间是去年,比较新,原帖见https://springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot-application/ ,但也不是没有问题,需要再改造一下才能完全适应项目开发,下面是改造后的大致的代码

  • application.yml
    1. spring:
    2. datasource:
    3. first:
    4. url: jdbc:postgresql://localhost:5432/sample
    5. driverClassName: org.postgresql.Driver
    6. username: postgres
    7. password: 111
    8. second:
    9. url: jdbc:oracle:thin:@//192.168.1.100:1521/orclpdb
    10. driverClassName: oracle.jdbc.OracleDriver
    11. username: webdba
    12. password: 111
    13. jpa:
    14. hibernate:
    15. ddl-auto: none
    16. show-sql: true

     

  • 数据源1的配置文件,postgre db
    需要注意的是,这里的每个方法都要使用Primary的注解,只有一个配置文件需要如此 ,这个是sb规定,否则启动时会报错,貌似任意一个都可以指定成这样的,不要被字面意思迷惑
    1. package com.xxx.config;
    2. import com.zaxxer.hikari.HikariDataSource;
    3. import org.springframework.beans.factory.annotation.Qualifier;
    4. import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
    5. import org.springframework.boot.context.properties.ConfigurationProperties;
    6. import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
    7. import org.springframework.context.annotation.Bean;
    8. import org.springframework.context.annotation.Configuration;
    9. import org.springframework.context.annotation.Primary;
    10. import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    11. import org.springframework.orm.jpa.JpaTransactionManager;
    12. import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    13. import org.springframework.transaction.PlatformTransactionManager;
    14. import org.springframework.transaction.annotation.EnableTransactionManagement;
    15. import javax.persistence.EntityManager;
    16. import javax.persistence.EntityManagerFactory;
    17. import javax.sql.DataSource;
    18. @Configuration
    19. @EnableTransactionManagement
    20. @EnableJpaRepositories(basePackages = "com.xxx.repo.first", //当前数据源对应的repository的包名,每个数据源应该有独立的包
    21. entityManagerFactoryRef = "firstEntityManagerFactory",
    22. transactionManagerRef= "firstTransactionManager"
    23. )
    24. public class FirstJpaConfig {
    25. @Bean
    26. @Primary
    27. @ConfigurationProperties("spring.datasource.first")
    28. public DataSourceProperties firstDataSourceProperties() {
    29. return new DataSourceProperties();
    30. }
    31. @Bean
    32. @Primary
    33. @ConfigurationProperties("spring.datasource.first.configuration")
    34. public DataSource firstDataSource() {
    35. return firstDataSourceProperties().initializeDataSourceBuilder()
    36. .type(HikariDataSource.class).build();
    37. }
    38. @Primary
    39. @Bean(name = "firstEntityManagerFactory")
    40. public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(EntityManagerFactoryBuilder builder) {
    41. return builder
    42. .dataSource(firstDataSource())
    43. .packages("com.xxx.entity.first") //当前数据源对应的实体的包名,每个数据源应该有独立的包
    44. .build();
    45. }
    46. @Primary
    47. @Bean
    48. public PlatformTransactionManager firstTransactionManager(
    49. final @Qualifier("firstEntityManagerFactory") LocalContainerEntityManagerFactoryBean firstEntityManagerFactory) {
    50. return new JpaTransactionManager(firstEntityManagerFactory.getObject());
    51. }
    52. @Primary
    53. @Bean(name = "firstEntityManager")
    54. //这个不是必须,但如果你想在service中注入一个EntityManager用于执行动态jql,这个就是必要的,否则,sb会不知道选择哪个EntityManager实例使用,每个数据源对应一个实例
    55. public EntityManager entityManager(@Qualifier("firstEntityManagerFactory") EntityManagerFactory factory) {
    56. return factory.createEntityManager();
    57. }
    58. }

     

  • 数据源2的配置文件,oracle db,和第一个高度类似,不解释了
    1. package com.xxx.config;
    2. import com.zaxxer.hikari.HikariDataSource;
    3. import org.springframework.beans.factory.annotation.Qualifier;
    4. import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
    5. import org.springframework.boot.context.properties.ConfigurationProperties;
    6. import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
    7. import org.springframework.context.annotation.Bean;
    8. import org.springframework.context.annotation.Configuration;
    9. import org.springframework.context.annotation.Primary;
    10. import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    11. import org.springframework.orm.jpa.JpaTransactionManager;
    12. import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    13. import org.springframework.transaction.PlatformTransactionManager;
    14. import org.springframework.transaction.annotation.EnableTransactionManagement;
    15. import javax.persistence.EntityManager;
    16. import javax.persistence.EntityManagerFactory;
    17. import javax.sql.DataSource;
    18. @Configuration
    19. @EnableTransactionManagement
    20. @EnableJpaRepositories(basePackages = "com.xxx.repo.second",
    21. entityManagerFactoryRef = "secondEntityManagerFactory",
    22. transactionManagerRef= "secondTransactionManager"
    23. )
    24. public class SecondJpaConfig {
    25. @Bean
    26. @ConfigurationProperties("spring.datasource.second")
    27. public DataSourceProperties secondDataSourceProperties() {
    28. return new DataSourceProperties();
    29. }
    30. @Bean
    31. @ConfigurationProperties("spring.datasource.second.configuration")
    32. public DataSource secondDataSource() {
    33. return secondDataSourceProperties().initializeDataSourceBuilder()
    34. .type(HikariDataSource.class).build();
    35. }
    36. @Bean(name = "secondEntityManagerFactory")
    37. public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(EntityManagerFactoryBuilder builder) {
    38. return builder
    39. .dataSource(secondDataSource())
    40. .packages("com.xxx.entity.second")
    41. .build();
    42. }
    43. @Bean
    44. public PlatformTransactionManager secondTransactionManager(
    45. final @Qualifier("secondEntityManagerFactory") LocalContainerEntityManagerFactoryBean secondEntityManagerFactory) {
    46. return new JpaTransactionManager(secondEntityManagerFactory.getObject());
    47. }
    48. @Bean(name = "secondEntityManager")
    49. public EntityManager entityManager(@Qualifier("secondEntityManagerFactory") EntityManagerFactory factory) {
    50. return factory.createEntityManager();
    51. }
    52. }

     

原帖中使用的数据源实现类是dbcp,听说目前性能最好的是Hikari数据源,我就替换了一下,测试运行良好。

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/52304
推荐阅读
相关标签
  

闽ICP备14008679号