前言
很多业务场景都需要使用到多数据库,本文介绍springboot对多数据源的使用。
1、pom.xml文件
和整合JPA的配置文件一样。
<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>
2、配置文件application.yml
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:
#主jpa配置
primary:
show-sql: true
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
#次jpa配置
secondary:
show-sql: true
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
3、配置数据源和JPA
- 主数据源
- @Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常。
- @Qualifier:一般@Autowired和@Qualifier一起用,通过name取多个实例中的一个。
- @ConfigurationProperties:根据配置文件中设置的属性,批量注入属性值。
@Configuration
public class PrimaryDataSourceConfig {
/**
* 扫描spring.datasource.primary开头的配置信息
*
* @return 数据源配置信息
*/
@Primary
@Bean(name = "primaryDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
/**
* 取主库数据源对象
*
* @param dataSourceProperties 注入名为primaryDataSourceProperties的bean
* @return 数据源对象
*/
@Primary
@Bean(name = "primaryDataSource")
public DataSource dataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
/**
* 该方法仅在需要使用JdbcTemplate对象时选用
*
* @param dataSource 注入名为primaryDataSource的bean
* @return 数据源JdbcTemplate对象
*/
@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注解对应的方法 |
@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";
/**
* 扫描spring.jpa.primary开头的配置信息
*
* @return jpa配置信息
*/
@Primary
@Bean(name = "primaryJpaProperties")
@ConfigurationProperties(prefix = "spring.jpa.primary")
public JpaProperties jpaProperties() {
return new JpaProperties();
}
/**
* 获取主库实体管理工厂对象
*
* @param primaryDataSource 注入名为primaryDataSource的数据源
* @param jpaProperties 注入名为primaryJpaProperties的jpa配置信息
* @param builder 注入EntityManagerFactoryBuilder
* @return 实体管理工厂对象
*/
@Primary
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(
@Qualifier("primaryDataSource") DataSource primaryDataSource,
@Qualifier("primaryJpaProperties") JpaProperties jpaProperties,
EntityManagerFactoryBuilder builder
) {
return builder
// 设置数据源
.dataSource(primaryDataSource)
// 设置jpa配置
.properties(jpaProperties.getProperties())
// 设置实体包名
.packages(ENTITY_PACKAGE)
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.persistenceUnit("primaryPersistenceUnit").build();
}
/**
* 获取实体管理对象
*
* @param factory 注入名为primaryEntityManagerFactory的bean
* @return 实体管理对象
*/
@Primary
@Bean(name = "primaryEntityManager")
public EntityManager entityManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
return factory.createEntityManager();
}
/**
* 获取主库事务管理对象
*
* @param factory 注入名为primaryEntityManagerFactory的bean
* @return 事务管理对象
*/
@Primary
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
}
- 次数据源
@Configuration
public class SecondaryDataSourceConfig {
/**
* 扫描spring.datasource.secondary开头的配置信息
*
* @return 数据源配置信息
*/
@Bean(name = "secondaryDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
/**
* 获取次数据源对象
*
* @param dataSourceProperties 注入名为secondaryDataSourceProperties的bean
* @return 数据源对象
*/
@Bean("secondaryDataSource")
public DataSource dataSource(@Qualifier("secondaryDataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
/**
* 该方法仅在需要使用JdbcTemplate对象时选用
*
* @param dataSource 注入名为secondaryDataSource的bean
* @return 数据源JdbcTemplate对象
*/
@Bean(name = "secondaryJdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
- 从Jpa配置
@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";
/**
* 扫描spring.jpa.secondary
*
* @return jpa配置信息
*/
@Bean(name = "secondaryJpaProperties")
@ConfigurationProperties(prefix = "spring.jpa.secondary")
public JpaProperties jpaProperties() {
return new JpaProperties();
}
/**
* 获取次库实体管理工厂对象
*
* @param secondaryDataSource 注入名为secondaryDataSource的数据源
* @param jpaProperties 注入名为secondaryJpaProperties的jpa配置信息
* @param builder 注入EntityManagerFactoryBuilder
* @return 实体管理工厂对象
*/
@Bean(name = "secondaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
@Qualifier("secondaryDataSource") DataSource secondaryDataSource,
@Qualifier("secondaryJpaProperties") JpaProperties jpaProperties,
EntityManagerFactoryBuilder builder
) {
return builder
// 设置数据源
.dataSource(secondaryDataSource)
// 设置jpa配置
.properties(jpaProperties.getProperties())
// 设置实体包名
.packages(ENTITY_PACKAGE)
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.persistenceUnit("secondaryPersistenceUnit").build();
}
/**
* 获取实体管理对象
*
* @param factory 注入名为secondaryEntityManagerFactory的bean
* @return 实体管理对象
*/
@Bean(name = "secondaryEntityManager")
public EntityManager entityManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) {
return factory.createEntityManager();
}
/**
* 获取主库事务管理对象
*
* @param factory 注入名为secondaryEntityManagerFactory的bean
* @return 事务管理对象
*/
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
}
4、实体类
- 主库实体类
@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;
}
}
- 从库实体类
@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;
}
}
5、Repository类
- 主库类
public interface CityRepository extends JpaRepository<City,Integer> {
}
- 从库类
public interface HouseRepository extends JpaRepository<House, Integer> {
}
6、Controller类
@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";
}
}