记录SpringBoot里JPA配置多数据源
之前的系统是建立在mysql数据库上的, 后来需求变更,需要跟教务系统对接获取教师的课表数据,在Oracle上。
baidu了之后找了几篇样例,写完了。发现只能连接@Primary的数据源。思索3天后,觉得应该是系统启动时自动就将Primary的数据源加载好了,并没有根据我的bean和mapper去匹配对应的数据源。(因为debug了好久没找到user,password在哪儿设置值的,,,我太蠢了。)又百度找了半天,发现在启动类里竟然还有个
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,.....这种配置。
现在将所有的代码发上来,记录一下,(过两年我可能又忘记了)
项目目录,关键位置分了mysql和oracle目录
Step1:引入依赖
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
Step2:数据库配置
spring.datasource.mysql.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.mysql.password=XXX
spring.datasource.mysql.username=XXX
spring.datasource.mysql.url=jdbc:mysql://localhost:3306/ledger
spring.datasource.oracle.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.oracle.password=XXXX
spring.datasource.oracle.username=XXXX
spring.datasource.oracle.url=jdbc:oracle:thin:@X.X.X.X:1521/racdb
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.OracleDialect
#jpa
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.jpa.hibernate.ddl-auto=update
spring.jpa.open-in-view=false
Step3:自定义datasource配置
主数据源Mysql:MysqlDataSourceConfig.java
@Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef="mysqlEntityManagerFactory", transactionManagerRef="mysqlTransactionManager", basePackages={"com.njjs.ledgersystem.mapper.mysql"}) @EntityScan(basePackages={"com.njjs.ledgersystem.entity.mysql"}) @MapperScan(basePackages={"com.njjs.ledgersystem.mapper.mysql"},sqlSessionFactoryRef = "mysqlSqlSessionFactory") public class MysqlDataSourceConfig { //加载properties文件中mysql数据源的相关配置 @Primary //主数据源 @Bean(name="mysqlDataSourceProperties") @ConfigurationProperties("spring.datasource.mysql") public DataSourceProperties mysqlDataSourceProperties(){ return new DataSourceProperties(); } //配置数据源 @Primary @Bean(name="mysqlDataSource") public DataSource mysqlDataSource(@Qualifier("mysqlDataSourceProperties") DataSourceProperties mysqlDtSource){ return mysqlDtSource.initializeDataSourceBuilder() .type(HikariDataSource.class) .build(); } //配置Session指定Mapper位置,不在Main启动类里去找了,在这里手动去找 @Primary @Bean(name="mysqlSqlSessionFactory") public SqlSessionFactory mysqlSqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception{ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/mysql/*.xml")); return bean.getObject(); } @Primary @Bean(name="mysqlSqlSessionTemplate") public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("mysqlSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception{ return new SqlSessionTemplate(sqlSessionFactory); } //配置连接工厂 @Primary @Bean(name="mysqlEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("mysqlDataSource") DataSource mysqlDataSource) { return builder.dataSource(mysqlDataSource) .packages("com.njjs.ledgersystem.entity.mysql") .persistenceUnit("mysql") .build(); } //事务管理 @Primary @Bean(name = "mysqlTransactionManager") public PlatformTransactionManager mysqlTransactionManager(final @Qualifier("mysqlEntityManagerFactory") LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory) { return new JpaTransactionManager(mysqlEntityManagerFactory.getObject()); } }
从数据源Oracle:OracleDataSourceConfig.java
@Configuration @EnableTransactionManagement @EnableJpaRepositories(entityManagerFactoryRef="oracleEntityManagerFactory", transactionManagerRef="oracleTransactionManager", basePackages={"com.njjs.ledgersystem.mapper.oracle"}) @EntityScan(basePackages={"com.njjs.ledgersystem.entity.oracle"}) @MapperScan(basePackages={"com.njjs.ledgersystem.mapper.oracle"},sqlSessionFactoryRef="oracleSqlSessionFactory") public class OracleDataSourceConfig { //加载properties文件中oracle数据源的相关配置 //@Primary @Bean(name="oracleDataSourceProperties") @ConfigurationProperties("spring.datasource.oracle") public DataSourceProperties oracleDataSourceProperties(){ return new DataSourceProperties(); } //配置数据源 //@Primary @Bean(name="oracleDataSource") public DataSource oracleDataSource(@Qualifier("oracleDataSourceProperties") DataSourceProperties oracleDtSource){ return oracleDtSource.initializeDataSourceBuilder() .type(HikariDataSource.class) .build(); } //配置Session指定Mapper位置,不在Main启动类里去找了,在这里手动去找 @Bean(name="oracleSqlSessionFactory") public SqlSessionFactory oracleSqlSessionFactory(@Qualifier("oracleDataSource") DataSource dataSource) throws Exception{ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/oracle/*.xml")); return bean.getObject(); } @Bean(name="oracleSqlSessionTemplate") public SqlSessionTemplate oracleSqlSessionTemplate(@Qualifier("oracleSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception{ return new SqlSessionTemplate(sqlSessionFactory); } //配置连接工厂 //@Primary @Bean(name="oracleEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("oracleDataSource") DataSource oracleDataSource) { return builder.dataSource(oracleDataSource) .packages("com.njjs.ledgersystem.entity.oracle") .persistenceUnit("oracle") .build(); } //事务管理 //@Primary @Bean(name = "oracleTransactionManager") public PlatformTransactionManager oracleTransactionManager(final @Qualifier("oracleEntityManagerFactory") LocalContainerEntityManagerFactoryBean oracleEntityManagerFactory) { return new JpaTransactionManager(oracleEntityManagerFactory.getObject()); } }
Step4: 在所有Mapper里写入注解
Step5:修改启动类,让他不要自己加载单一数据源,有我们自定义的datasource里自己去处理Mapper,entity,数据库连接参数等等。
@EnableScheduling @SpringBootApplication(exclude={DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, MybatisAutoConfiguration.class}) public class LedgerSystemApplication{ private static final Logger logger = LogManager.getLogger(); public static void main(String[] args) { SpringApplication.run(LedgerSystemApplication.class, args); } }
测试通过,爽歪歪