前言
很多业务场景都需要使用到多数据库,本文介绍springboot对多数据源的使用。
pom.xml文件
和整合JPA的配置文件一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
|
配置文件application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| server: port: 8080 spring: datasource: primary: url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource secondary: url: jdbc:mysql://localhost:3306/test2?serverTimezone=GMT username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver jpa: primary: show-sql: true properties: hibernate: hbm2ddl: auto: update dialect: org.hibernate.dialect.MySQL5InnoDBDialect secondary: show-sql: true properties: hibernate: hbm2ddl: auto: update dialect: org.hibernate.dialect.MySQL5InnoDBDialect
|
配置数据源和JPA
主数据源配置
主数据源
- @Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常。
- @Qualifier:一般@Autowired和@Qualifier一起用,通过name取多个实例中的一个。
- @ConfigurationProperties:根据配置文件中设置的属性,批量注入属性值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| @Configuration public class PrimaryDataSourceConfig {
@Primary @Bean(name = "primaryDataSourceProperties") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); }
@Primary @Bean(name = "primaryDataSource") public DataSource dataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties dataSourceProperties) { return dataSourceProperties.initializeDataSourceBuilder().build(); }
@Primary @Bean(name = "primaryJdbcTemplate") public JdbcTemplate jdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
|
主Jpa配置
- @EnableTransactionManagement:使用注解@EnableTransactionManagement开启事务支持后,可以在访问数据库的Service方法上添加注解 @Transactional 使用事务。
- @EnableJpaRepositories:用于Srping JPA的代码配置(详细介绍)
属性 |
功能 |
basePackage |
用于配置扫描Repositories所在的package及子package。 |
entityManagerFactoryRef |
实体管理工厂引用名称,对应到@Bean注解对应的方法。 |
transactionManagerRef |
事务管理工厂引用名称,对应到@Bean注解对应的方法 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| @Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = PrimaryJpaConfig.REPOSITORY_PACKAGE, entityManagerFactoryRef = "primaryEntityManagerFactory", transactionManagerRef = "primaryTransactionManager" ) public class PrimaryJpaConfig {
static final String REPOSITORY_PACKAGE = "com.huzh.springbootjpamulidatasource.repository.primary"; private static final String ENTITY_PACKAGE = "com.huzh.springbootjpamulidatasource.entity.primary";
@Primary @Bean(name = "primaryJpaProperties") @ConfigurationProperties(prefix = "spring.jpa.primary") public JpaProperties jpaProperties() { return new JpaProperties(); }
@Primary @Bean(name = "primaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean( @Qualifier("primaryDataSource") DataSource primaryDataSource, @Qualifier("primaryJpaProperties") JpaProperties jpaProperties, EntityManagerFactoryBuilder builder ) { return builder .dataSource(primaryDataSource) .properties(jpaProperties.getProperties()) .packages(ENTITY_PACKAGE) .persistenceUnit("primaryPersistenceUnit").build(); }
@Primary @Bean(name = "primaryEntityManager") public EntityManager entityManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) { return factory.createEntityManager(); }
@Primary @Bean(name = "primaryTransactionManager") public PlatformTransactionManager transactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) { return new JpaTransactionManager(factory); } }
|
次数据源配置
次数据源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @Configuration public class SecondaryDataSourceConfig {
@Bean(name = "secondaryDataSourceProperties") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); }
@Bean("secondaryDataSource") public DataSource dataSource(@Qualifier("secondaryDataSourceProperties") DataSourceProperties dataSourceProperties) { return dataSourceProperties.initializeDataSourceBuilder().build(); }
@Bean(name = "secondaryJdbcTemplate") public JdbcTemplate jdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
|
从Jpa配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| @Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = SecondaryJpaConfig.REPOSITORY_PACKAGE, entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager" ) public class SecondaryJpaConfig {
static final String REPOSITORY_PACKAGE = "com.huzh.springbootjpamulidatasource.repository.secondary"; private static final String ENTITY_PACKAGE = "com.huzh.springbootjpamulidatasource.entity.secondary";
@Bean(name = "secondaryJpaProperties") @ConfigurationProperties(prefix = "spring.jpa.secondary") public JpaProperties jpaProperties() { return new JpaProperties(); }
@Bean(name = "secondaryEntityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( @Qualifier("secondaryDataSource") DataSource secondaryDataSource, @Qualifier("secondaryJpaProperties") JpaProperties jpaProperties, EntityManagerFactoryBuilder builder ) { return builder .dataSource(secondaryDataSource) .properties(jpaProperties.getProperties()) .packages(ENTITY_PACKAGE) .persistenceUnit("secondaryPersistenceUnit").build(); }
@Bean(name = "secondaryEntityManager") public EntityManager entityManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) { return factory.createEntityManager(); }
@Bean(name = "secondaryTransactionManager") public PlatformTransactionManager transactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) { return new JpaTransactionManager(factory); } }
|
实体类
主库实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| @Entity @Table(name="city") public class City {
@Id @GeneratedValue(strategy=GenerationType.AUTO) private int cityId; private String cityName; private String cityIntroduce;
public City(int cityId, String cityName, String cityIntroduce) { this.cityId = cityId; this.cityName = cityName; this.cityIntroduce = cityIntroduce; }
public City(String cityName, String cityIntroduce) { this.cityName = cityName; this.cityIntroduce = cityIntroduce; }
public City() { }
public int getCityId() { return cityId; }
public void setCityId(int cityId) { this.cityId = cityId; }
public String getCityName() { return cityName; }
public void setCityName(String cityName) { this.cityName = cityName; }
public String getCityIntroduce() { return cityIntroduce; }
public void setCityIntroduce(String cityIntroduce) { this.cityIntroduce = cityIntroduce; } }
|
从库实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| @Entity @Table(name = "house") public class House {
@Id @GeneratedValue(strategy = GenerationType.AUTO) private int houseId; private String houseName; private String houseIntroduce;
public int getHouseId() { return houseId; }
public void setHouseId(int houseId) { this.houseId = houseId; }
public String getHouseName() { return houseName; }
public void setHouseName(String houseName) { this.houseName = houseName; }
public String getHouseIntroduce() { return houseIntroduce; }
public void setHouseIntroduce(String houseIntroduce) { this.houseIntroduce = houseIntroduce; }
public House(String houseName, String houseIntroduce) { this.houseName = houseName; this.houseIntroduce = houseIntroduce; } }
|
Repository类
主库类
1 2
| public interface CityRepository extends JpaRepository<City,Integer> { }
|
从库类
1 2
| public interface HouseRepository extends JpaRepository<House, Integer> { }
|
Controller类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @RestController public class TestController {
@Autowired CityRepository cityRepository;
@Autowired HouseRepository houseRepository;
@GetMapping("/testDataSource") public String testDataSource() { City city = new City("北京", "中国首都"); cityRepository.save(city); return "success"; }
@GetMapping("/testDataSource2") public String testDataSource2() { House house = new House("豪宅", "特别大的豪宅"); houseRepository.save(house); return "success"; }
}
|