maven 配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
application.properties 配置
配置两个数据源
## 数据源1
user.datasource.jdbc-url=jdbc:mysql://localhost:3306/test
user.datasource.username=root
user.datasource.password=root
## 数据源2
product.datasource.jdbc-url=jdbc:mysql://172.16.28.3:6606/test
product.datasource.username=root
product.datasource.password=meitu.com
数据实例
构建两个实例与两个数据源中的表格对应
user
@Entity
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
)
product
@Entity
@Getter
@Setter
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
)
包结构
为了读取不同数据源的配置,根据包结构来对配置进行区分
src/main/java
- com.wbl.springDemo
- produce
- data
- repo
- config
- user
- data
- repo
- config
ProductDao
@Repository
public interface ProductDao extends JpaRepository<Product, Integer> {
}
UserDao
@Repository
public interface UserDao extends JpaRepository<User, Integer> {
}
数据源配置
user配置
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "userEntityManagerFactory",
transactionManagerRef = "userTransactionManager",
basePackages = {
"com.wbl.spingbootdemo.muldatasource.user.repo"
}
)
public class UserConfig {
@Primary
@Bean("userDatasource")
@ConfigurationProperties("user.datasource")
public HikariDataSource userDatasource(){
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Primary
@Bean("userEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("userDatasource")DataSource dataSource){
return builder.dataSource(dataSource)
.packages("com.wbl.spingbootdemo.muldatasource.user.data")
.persistenceUnit("db1")
.build();
}
@Primary
@Bean("userTransactionManager")
public PlatformTransactionManager userTransactionManager(@Qualifier("userEntityManagerFactory") EntityManagerFactory entityManagerFactory){
return new JpaTransactionManager(entityManagerFactory);
}
}
product 配置
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "productEntityManagerFactory",
transactionManagerRef = "productTransactionManager",
basePackages = {
"com.wbl.spingbootdemo.muldatasource.product.repo"
}
)
public class ProductConfig {
@Bean("productDatasource")
@ConfigurationProperties(prefix = "product.datasource")
public DataSource productDatasource(){
return DataSourceBuilder.create().build();
}
@Bean("productEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean productEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("productDatasource")DataSource productDatasource){
return builder.dataSource(productDatasource)
.packages("com.wbl.spingbootdemo.muldatasource.product.data")
.persistenceUnit("db2")
.build();
}
@Bean(name = "productTransactionManager")
public PlatformTransactionManager productTransactionManager(
@Qualifier("productEntityManagerFactory") EntityManagerFactory productEntityManagerFactory
) {
return new JpaTransactionManager(productEntityManagerFactory);
}
}
其中@Primary的作用是,在对同一接口有几种不同实现时,告诉spring默认注入哪个实例
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class MultipleDataSourcesProductTests {
@Autowired
ProductDao productDao;
@Test
@Transactional("productTransactionManager")
public void testSaveProduct(){
Product product = new Product();
product.setName("product1");
product = productDao.save(product);
Assert.assertNotNull(productDao.findById(product.getId()));
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class MultipleDataSourcesUserTests {
@Autowired
private UserDao userDao;
@Test
// @Transactional("userTransactionManager")
public void testSaveUser(){
User user = new User();
user.setName("name");
userDao.save(user);
}
}
其中加入@Transactional注解,数据不会真正保存在数据库中
总结
spring boot 多数据源配置步骤总结
- 配置application.properties,填入数据源的详细信息
- 生成entity
- 生成entity对应的Repository
- 配置entityManager以及TransactionManager(事务管理)