本方案是兩個數據源分開獨立,事務獨自管理,沒有做分布式事務方案,沒有做動態數據源切換,應用在一個模塊簡單集成多個數據源,獨立操作各自數據庫,事務不交叉的場景
1.pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<mysql.version>8.0.15</mysql.version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.15</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
</dependencies>
2.配置文件,用的yml
spring: datasource: tax: name: tax url: jdbc:oracle:thin:@xxxx:ORCL username: xxx password: xx type: com.alibaba.druid.pool.DruidDataSource initialSize: 2 readSize: 2 minIdle: 2 maxActive: 10 maxWait: 60000 timeBetweenEvictionRunsMillis: 3600000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 filters: stat,wall,slf4j connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 police: name: police url: jdbc:mysql://xxx?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true username: xxxx password: xxxx type: com.alibaba.druid.pool.DruidDataSource initialSize: 2 readSize: 2 minIdle: 2 maxActive: 10 maxWait: 60000 timeBetweenEvictionRunsMillis: 3600000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 filters: stat,wall,slf4j connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
3.獨立的數據源、事務配置
按不同的數據源建立不同的包,一個數據源對應一個包,把相應的entity和repository都建在這個包,配置entity和repository掃描這個包
@Configuration @EnableJpaRepositories(entityManagerFactoryRef = "policeEntityManagerFactory", transactionManagerRef = "policeTransactionManager", //設置repository所在位置 basePackages = {"org.police.domain.repository"} ) public class PoliceDataSourceConfig { @Bean("policeDataSource") @ConfigurationProperties(prefix = "spring.datasource.police") public DataSource dataSource() { DruidDataSource datasource = new DruidDataSource(); return datasource; } @Bean(name = "policeEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(JpaUtil.getHibernateJpaVendorAdapter(Database.MYSQL)); factory.setJpaPropertyMap(JpaUtil.getJpaPropertyMap()); //設置實體類位置 factory.setPackagesToScan("org.police.domain.entity"); factory.setDataSource(dataSource()); return factory; } @Bean(name = "policeTransactionManager") public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory); return txManager; } }
@Configuration @EnableJpaRepositories(entityManagerFactoryRef = "taxEntityManagerFactory", transactionManagerRef = "taxTransactionManager", //設置repository所在位置 basePackages = {"org.tax.domain.repository"} ) public class TaxDataSourceConfig { @Bean("taxDataSource") @ConfigurationProperties(prefix = "spring.datasource.tax") @Primary public DataSource dataSource() { DruidDataSource datasource = new DruidDataSource(); return datasource; } @Bean(name = "taxEntityManagerFactory") @Primary public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(JpaUtil.getHibernateJpaVendorAdapter(Database.ORACLE)); factory.setJpaPropertyMap(JpaUtil.getJpaPropertyMap()); //設置實體類位置 factory.setPackagesToScan("org.tax.domain.entity"); factory.setDataSource(dataSource()); return factory; } @Bean(name = "taxTransactionManager") @Primary public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory); return txManager; } }
public class JpaUtil { /** * 設置hibernate的屬性 * @return */ public static HibernateJpaVendorAdapter getHibernateJpaVendorAdapter(Database database){ HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(false); vendorAdapter.setShowSql(true); vendorAdapter.setDatabase(database); return vendorAdapter; } /** * 設置hibernate的屬性 * @return */ public static Map<String, Object> getJpaPropertyMap(){ Map<String, Object> properties = new HashMap<>(1); properties.put(Environment.FORMAT_SQL,true); return properties; } }
