SpringBoot多数据库连接(mysql+oracle)

您所在的位置:网站首页 springboot连接两个数据库 SpringBoot多数据库连接(mysql+oracle)

SpringBoot多数据库连接(mysql+oracle)

2024-07-11 00:47| 来源: 网络整理| 查看: 265

mysql(springboot)【primary,优先搜寻该数据库】:mysql数据库,包含User的信息 oracle(springboot): oracle数据库, 包含Country信息 项目依赖 为了支持Mysql和Oracle数据库,我们必须要在pom.xml文件中添加相应的依赖。

com.oracle ojdbc6 11.2.0.3.0 compile mysql mysql-connector-java org.springframework.boot spring-boot-starter-data-jpa javax.persistence javax.persistence-api 2.2 org.projectlombok lombok 1.18.12 包管理 为了方便代码的开发,我们将mysql和oracle分开放在两个不同的package下面,具体的包结构如下:

将不同的模型分开放入mysql和oracle包目录下,需要注意的是,mysql和oracle为两个不同的数据库,所以两个数据库中可能存在某个表名称一致的场景。该场景下,会优先匹配primary的数据库,如果该数据库down了,才会匹配另外一张表。所以,如果想要两张表都正常使用,建议使用不同的Entity名称。

数据库连接配置 我们在属性文件application.properties中分别配置两个单独的jdbc连接,将所有关联的Entity类和Repository映射到两个不同的包中。

## jdbc-primary spring.datasource.url=jdbc:mysql://localhost:33306/springboot?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false spring.datasource.username=springboot spring.datasource.password=123456 spring.ds_mysql.driverClassName=com.mysql.jdbc.Driver ## jdbc-second spring.second.datasource.url=jdbc:oracle:thin:@localhost:1909/xxx.xxx.com spring.second.datasource.userName=springboot spring.second.datasource.password=123456 spring.second.datasource.driver-class-name=oracle.jdbc.OracleDriver ## jpa spring.jpa.hibernate.ddl-auto=none spring.jpa.show-sql=true spring.jpa.properties.hibernate.jdbc.time_zone=UTC spring.jpa.properties.hibernate.jdbc.fetch_size=500 spring.jpa.properties.hibernate.jdbc.batch_size=100 数据源配置 需要注意的是,在配置多个数据源期间,必须将其中一个数据源标记为primary,否则Spring Boot会检测到多个类型的数据源,从而无法正常启动。 定义Data Source的Bean 想要创建Data Source,我们必须先实例化org.springframework.boot.autoconfigure.jdbc.DataSourceProperties类,加载application.properties文件中配置的数据库连接信息,并通过DataSourceProperties对象的初始化builder方法创建一个javax.sql.DataSource对象。 primary Data Source

@Primary @Bean(name = "mysqlDataSourceProperties") @ConfigurationProperties("spring.datasource") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); } @Primary @Bean(name = "mysqlDataSource") @ConfigurationProperties("spring.datasource.configuration") public DataSource dataSource (@Qualifier("mysqlDataSourceProperties") DataSourceProperties mysqlDataSourceProperties) { return mysqlDataSourceProperties.initializeDataSourceBuilder() .type(HikariDataSource.class) .build(); } Secondary Data Source @Bean(name = "oracleDataSourceProperties") @ConfigurationProperties("spring.second.datasource") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); } @Bean @ConfigurationProperties("spring.second.datasource.configuration") public DataSource oracleDataSource(@Qualifier("oracleDataSourceProperties") DataSourceProperties oracleDataSourceProperties) { return oracleDataSourceProperties.initializeDataSourceBuilder() .type(HikariDataSource.class) .build(); }

我们使用@Qualifier注解,自动关联指定的DataSourceProperties.

定义实体类管理工厂的Bean 上面说了,应用程序使用Spring Data JPA的repository接口将我们从实体管理器(Entity Manager)中抽象出来,从而进行数据的访问。这里,我们使用org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean这个Bean来创建EM实例,后面利用这个EM实例与JPA entities进行交互。 由于我们这里有两个数据源,所以我要为每个数据源单独创建一个EntityManagerFactory。 Primary Entity Manager Factory @Primary @Bean(name = "mysqlEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("mysqlDataSource") DataSource mysqlDataSource) { return builder.dataSource(mysqlDataSource) .packages("com.example.demo.model.mysql") .persistenceUnit("mysql") .build(); } Secondary Entity Manager Factory

@Bean(name = "oracleEntityManagerFactory") public LocalContainerEntityManagerFactoryBean oracleEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("oracleDataSource") DataSource oracleDataSource) { return builder.dataSource(oracleDataSource) .packages("com.example.demo.model.oracle") .persistenceUnit("oracle") .build(); } 我们使用@Qualifie注解,自动将DataSource关联到对应的EntityManangerFactory中。 在这里我们可以分别配置实体类管理工厂所管理的packages,为了方便开发和阅读,分别将mysql和oracle关联的实体类放在对应的目录下。 事务管理 我们为每个数据库创建一个JPA事务管理器。 查看源码我们可以发现JPA事务管理器需要EntityManangerFactory作为入参,所以利用上述定义的EntityMangerFactory分别生成对应的JPA事物管理器。 源码:

public JpaTransactionManager(EntityManagerFactory emf) { this(); this.entityManagerFactory = emf; this.afterPropertiesSet(); } Primary transaction manager

@Primary @Bean(name = "mysqlTransactionManager") public PlatformTransactionManager mysqlTransactionManager(final @Qualifier("mysqlEntityManagerFactory") LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory) { return new JpaTransactionManager(mysqlEntityManagerFactory.getObject()); } Secondary transaction manager

@Bean(name = "oracleTransactionManager") public PlatformTransactionManager oracleTransactionManager( final @Qualifier("oracleEntityManagerFactory") LocalContainerEntityManagerFactoryBean oracleEntityManagerFactory) { return new JpaTransactionManager(oracleEntityManagerFactory.getObject()); } JPA Repository配置 由于我们使用了两个不同的数据源,所以我们必须使用@EnableJpaRepositories注解为每个数据源提供特定的信息。 进入该注解源码,我们可以发现默认值如下:

/** * Annotation to enable JPA repositories. Will scan the package of the annotated configuration class for Spring Data * repositories by default. * * @author Oliver Gierke * @author Thomas Darimont */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(JpaRepositoriesRegistrar.class) public @interface EnableJpaRepositories { /** * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with) this * attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names. */ String[] basePackages() default {}; /** * Configures the name of the {@link EntityManagerFactory} bean definition to be used to create repositories * discovered through this annotation. Defaults to {@code entityManagerFactory}. * * @return */ String entityManagerFactoryRef() default "entityManagerFactory"; /** * Configures the name of the {@link PlatformTransactionManager} bean definition to be used to create repositories * discovered through this annotation. Defaults to {@code transactionManager}. * * @return */ String transactionManagerRef() default "transactionManager"; } 这里仅列了一些我们关心的方法。 从源码我中我们可以看见, basePackages: 使用此字段设置Repository的基本包,必须指向软件包中repository所在目录。 entityManagerFactoryRef:使用此字段引用默认或自定义的Entity Manager Factory, 这里通过Bean的名称进行指定, 默认Bean为entityManagerFactory。 transactionManagerRef:使用此字段引用默认或自定义的事务管理器,这里通过Bean的名称进行指定,默认Bean为transactionManager。 通过上面的内容,我们为两个不同的数据源分别定义了不同的名称,所以我们需要在这里分别将其注入容器中。 Primary

@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = {"com.example.demo.repository.mysql"}, entityManagerFactoryRef = "mysqlEntityManagerFactory", transactionManagerRef = "mysqlTransactionManager") public class MysqlDataSourceConfiguration { ... } secondary

@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.example.demo.repository.oracle", entityManagerFactoryRef = "oracleEntityManagerFactory", transactionManagerRef = "oracleTransactionManager") public class OracleDataSourceConfiguration { ... } 完整的配置文件 primary

@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = {"com.example.demo.repository.mysql"}, entityManagerFactoryRef = "mysqlEntityManagerFactory", transactionManagerRef = "mysqlTransactionManager") public class MysqlDataSourceConfiguration { @Primary @Bean(name = "mysqlDataSourceProperties") @ConfigurationProperties("spring.datasource") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); } @Primary @Bean(name = "mysqlDataSource") @ConfigurationProperties("spring.datasource.configuration") public DataSource dataSource (@Qualifier("mysqlDataSourceProperties") DataSourceProperties mysqlDataSourceProperties) { return mysqlDataSourceProperties.initializeDataSourceBuilder() .type(HikariDataSource.class) .build(); } @Primary @Bean(name = "mysqlEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("mysqlDataSource") DataSource mysqlDataSource) { return builder.dataSource(mysqlDataSource) .packages("com.example.demo.model.mysql") .persistenceUnit("mysql") .build(); } @Primary @Bean(name = "mysqlTransactionManager") public PlatformTransactionManager transactionManager(final @Qualifier("mysqlEntityManagerFactory") LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory) { return new JpaTransactionManager(mysqlEntityManagerFactory.getObject()); } } secondary

@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.example.demo.repository.oracle", entityManagerFactoryRef = "oracleEntityManagerFactory", transactionManagerRef = "oracleTransactionManager") public class OracleDataSourceConfiguration { @Bean(name = "oracleDataSourceProperties") @ConfigurationProperties("spring.second.datasource") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); } @Bean @ConfigurationProperties("spring.second.datasource.configuration") public DataSource oracleDataSource(@Qualifier("oracleDataSourceProperties") DataSourceProperties oracleDataSourceProperties) { return oracleDataSourceProperties.initializeDataSourceBuilder() .type(HikariDataSource.class) .build(); } @Bean(name = "oracleEntityManagerFactory") public LocalContainerEntityManagerFactoryBean oracleEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("oracleDataSource") DataSource oracleDataSource) { return builder.dataSource(oracleDataSource) .packages("com.example.demo.model.oracle") .persistenceUnit("oracle") .build(); } @Bean public PlatformTransactionManager oracleTransactionManager( final @Qualifier("oracleEntityManagerFactory") LocalContainerEntityManagerFactoryBean oracleEntityManagerFactory) { return new JpaTransactionManager(oracleEntityManagerFactory.getObject()); } } 总结 当仅有一个数据源时,Spring Boot会默认自动配置好,但是如果使用多个数据源时,需要进行一些自定义的配置,以上便是全部的配置。 总体感觉并不是特别复杂,耐心理解下,还是很容易理解的。 如有错漏之处,还望各位大佬们指正。    作者:吴家二少 博客地址:https://www.cnblogs.com/wu-kai/ 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接 


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3