springboot-jpa多数据源
- Maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
- application.yml
spring: datasource: #默认type:HikariDataSource 号称java最快的连接池 primary: jdbcUrl: jdbc:mysql://127.0.0.1:3306/heyday?useUnicode=true&characterEncoding=utf8 username: root password: root maximum-pool-size: 30 minimum-idle: 5 secondary: jdbcUrl: jdbc:mysql://127.0.0.1:3306/heyday2?useUnicode=true&characterEncoding=utf8 username: root password: root maximum-pool-size: 30 minimum-idle: 5 jpa: hibernate: naming: physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
- Java配置类
- DataSourceConfig
package com.jinjian.demo.config; import com.zaxxer.hikari.HikariDataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Bean("primaryDataSource") @Primary @ConfigurationProperties("spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); //返回的DataSource对象会被@ConfigurationProperties进行属性注入 } @Bean("secondaryDataSource") @ConfigurationProperties("spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); } }
- PrimaryConfig
package com.jinjian.demo.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactoryPrimary", transactionManagerRef="transactionManagerPrimary", basePackages= { "com.jinjian.demo.repository.primary" }) public class PrimaryConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired private JpaProperties jpaProperties; //Jpa自带的一个读取jpa属性的类 @Bean("entityManagerFactoryPrimary") @Primary public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); //hibernate基本配置 vendorAdapter.setDatabase(Database.MYSQL); vendorAdapter.setShowSql(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.jinjian.demo.pojo.primary"); //实体扫描 factory.setDataSource(primaryDataSource); Map<String, Object> hibernateProperties = jpaProperties.getHibernateProperties(new HibernateSettings()); factory.setJpaPropertyMap(hibernateProperties); //主要目的:读取application.yml的naming-strategy,并设置进去,不然实体属性与表字段之间无法进行驼峰->下划线的自动转换,本来默认就是自动转换的。但是你是配的多个自定义数据源,spring特性之一,一旦自定义,默认不生效,了解一下...
return factory; } @Bean("transactionManagerPrimary") @Primary public PlatformTransactionManager transactionManagerPrimary() { //事务管理器:事务不能跨数据源,跨数据源,事务是不生效的。使用事务时,最好要指明使用哪个事务管理器,不然就会默认使用primary修饰的事务管理器 JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactoryPrimary().getObject()); return txManager; } } -
SecondaryConfig
package com.jinjian.demo.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactorySecondary", transactionManagerRef="transactionManagerSecondary", basePackages= { "com.jinjian.demo.repository.secondary" }) public class SecondaryConfig { @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Autowired private JpaProperties jpaProperties; @Bean("entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); vendorAdapter.setDatabase(Database.MYSQL); vendorAdapter.setShowSql(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.jinjian.demo.pojo.secondary"); factory.setDataSource(secondaryDataSource); Map<String, Object> hibernateProperties = jpaProperties.getHibernateProperties(new HibernateSettings()); factory.setJpaPropertyMap(hibernateProperties); return factory; } @Bean("transactionManagerSecondary") public JpaTransactionManager transactionManagerSecondary() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactorySecondary().getObject()); return transactionManager; } }
-
POJO与Repository包结构
- 如何在service中使用
package com.jinjian.demo.service; import com.jinjian.demo.pojo.secondary.Tclient; import com.jinjian.demo.repository.secondary.TclientRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class TclientService { @Autowired private TclientRepository tclientRepository; @Transactional("transactionManagerSecondary") //非主事务管理器,必须写明用的是哪个,不然用的别就是默认数据源的事务管理器,就无效。 public void addTclient(Tclient tclient){ tclientRepository.delete(tclient); if (1 == 1){ throw new RuntimeException("测试"); } tclientRepository.save(tclient); } }
- DataSourceConfig